Patch for bugs in errorhandling in PEAR 1.3

From: Date: Wed, 03 Mar 2004 10:30:42 +0000
Subject: Patch for bugs in errorhandling in PEAR 1.3
Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-26050@lists.php.net to get a copy of this message
Hi! Due to the fact that nobody replied to my last mail, I'll try it twice. The errorhandling of PEAR contains some bugs regarding how to detect if a method is called staticly or not. In PEAR 1.3 the check for isset($this) in methods like setErrorHandling() was replaced by isset($this) && is_a($this, 'PEAR') I already pointed out that this solution isn't safe, too. I attached a file called reproduce.php. The expected output is: first try: I'm dead! But you'll see: first try: He's still alive! second try: I'm dead! After applying the patch for PEAR.php of PEAR 1.3 I attached (patch_for_PEAR_1_3.txt) you'll get the expected output! Note: The patch only works for PHP 4.3. PHP versions before 4.3 aren't affected and the behaviour is the same as before. I hope to get some feedback this time. Regards Markus

--- PEAR_original.php 2004-02-09 10:03:10.000000000 +0100 +++ PEAR.php 2004-03-03 10:56:07.000000000 +0100 @@ -297,7 +297,7 @@ function setErrorHandling($mode = null, $options = null) { - if (isset($this) && is_a($this, 'PEAR')) { + if (isset($this) && is_a($this, 'PEAR') && !PEAR::isCalledStaticly()) { $setmode = &$this->_default_error_mode; $setoptions = &$this->_default_error_options; } else { @@ -501,7 +501,7 @@ $message = $message->getMessage(); } - if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) { + if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors)) && !PEAR::isCalledStaticly()) { if ($exp[0] == "*" || (is_int(reset($exp)) && in_array($code, $exp)) || (is_string(reset($exp)) && in_array($message, $exp))) { @@ -523,7 +523,7 @@ if ($error_class !== null) { $ec = $error_class; - } elseif (isset($this) && isset($this->_error_class)) { + } elseif (isset($this) && isset($this->_error_class) && !PEAR::isCalledStaticly()) { $ec = $this->_error_class; } else { $ec = 'PEAR_Error'; @@ -549,7 +549,7 @@ $code = null, $userinfo = null) { - if (isset($this) && is_subclass_of($this, 'PEAR_Error')) { + if (isset($this) && is_a($this, 'PEAR') && !PEAR::isCalledStaticly()) { return $this->raiseError($message, $code, null, null, $userinfo); } else { return PEAR::raiseError($message, $code, null, null, $userinfo); @@ -574,7 +574,7 @@ function pushErrorHandling($mode, $options = null) { $stack = &$GLOBALS['_PEAR_error_handler_stack']; - if (isset($this) && is_a($this, 'PEAR')) { + if (isset($this) && is_a($this, 'PEAR') && !PEAR::isCalledStaticly()) { $def_mode = &$this->_default_error_mode; $def_options = &$this->_default_error_options; } else { @@ -583,7 +583,7 @@ } $stack[] = array($def_mode, $def_options); - if (isset($this) && is_a($this, 'PEAR')) { + if (isset($this) && is_a($this, 'PEAR') && !PEAR::isCalledStaticly()) { $this->setErrorHandling($mode, $options); } else { PEAR::setErrorHandling($mode, $options); @@ -608,7 +608,7 @@ array_pop($stack); list($mode, $options) = $stack[sizeof($stack) - 1]; array_pop($stack); - if (isset($this) && is_a($this, 'PEAR')) { + if (isset($this) && is_a($this, 'PEAR') && !PEAR::isCalledStaticly()) { $this->setErrorHandling($mode, $options); } else { PEAR::setErrorHandling($mode, $options); @@ -650,6 +650,25 @@ } // }}} + + /** + * Detects if a method is called staticly. + * + * @return bool true, if staticly + * false, if not staticly or PHP < 4.3 + * @access public + * @author Markus Kalkbrenner + */ + function isCalledStaticly() + { + if (function_exists("debug_backtrace")) { + // PHP >= 4.3 + $stack = debug_backtrace(); + if ("::" == $stack[1]["type"]) return true; + } + + return false; + } } // {{{ _PEAR_call_destructors() Attachment: [text/x-c++src] reproduce.php
« previous php.pear.dev (#26050) next »