Patch for bugs in errorhandling in PEAR 1.3
| From: | Markus Kalkbrenner | 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
--- 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