Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 1.10.15

Bug #1444 PEAR_ErrorStack->push() needs to validate $msg and $code as string/int
Submitted: 2004-05-19 16:31 UTC
From: jon dot bertsch at ucop dot edu Assigned: cellog
Status: Closed Package: PEAR
PHP Version: 5.0.0RC2 (Release Candidate 2) OS: n/a
Roadmaps: (Not assigned)    
Subscription  


 [2004-05-19 16:31 UTC] jon dot bertsch at ucop dot edu
Description: ------------ Running PHP5 (RC2) you get an error when using PEAR_ErrorStack. In PHP version 4.3.2 it works fine. I'm not sure whether this should go to this section or under php5 bugs. Reproduce code: --------------- require_once 'PEAR/ErrorStack.php'; require_once 'Log.php'; $query = "SELECT * FROM myDb"; $dsn = array('phptype' => 'mysql', 'hostspec' => 'localhost', 'database' => 'test', 'username' => 'user', 'password' => 'pass'); // version 1: stack instance access $stack = &PEAR_ErrorStack::singleton('MyPackage'); $stack -> push (MYPACKAGE_ERROR_TEST, 'error', array('query' => $query, 'dsn' => $dsn), 'TEST error: add to stack'); $error_list = $stack -> getErrors(); print_r($error_list); echo ":: END ::"; Expected result: ---------------- In php 4.3.2: Array ( [0] => Array ( [code] => MYPACKAGE_ERROR_TEST [params] => Array ( [query] => SELECT * FROM myDb [dsn] => Array ( [phptype] => mysql [hostspec] => localhost [database] => test [username] => user [password] => pass ) ) [package] => MyPackage [level] => error [time] => 1084983362.0052 [context] => Array ( [file] => /Library/WebServer/Documents/ pear_errorstack_test.php [line] => 19 ) [message] => TEST error: add to stack ) ) :: END :: Actual result: -------------- In php5 RC2: Fatal error: Wrong parameter count for exception([string $exception [, long $code ]]) in Unknown on line 0 I think it's at the call to _exceptionClass around line 450 under the push method but I'm not certain

Comments

 [2004-05-19 21:02 UTC] dufuz
changing the summary.
 [2004-05-19 22:04 UTC] jon dot bertsch at ucop dot edu
Since I was working on a new server I also tested this same code on Linux (SUSE 9) against a new install of php4.3.6 and the code gave the expected print out of the stack error array. When I then changed the http.conf to use php5.0RC2 I saw the same error as described in the original report.
 [2004-05-19 22:55 UTC] cellog
You may have found a bug in PHP, actually. The line in question: $ret = new $exception($msg, $code); clearly has only 2 parameters to the exception. I will not have time to investigate this until June, most likely, so if you can, try changing the code to $ret = new Exception($msg, $code); and see if it still has the same error. I also wonder about the in Unknown on line 0 - are you using eval() or some other strange sequence? Perhaps there is another class extending Exception that is calling parent::__construct() with the wrong parameter count? Greg
 [2004-05-20 15:40 UTC] jon dot bertsch at ucop dot edu
I tried the substitution that you suggested but it didn't work I spent a little time looking at the code more closely. I found that the definition in the documentation for the push method is the following: PEAR_Error|array|Exception PEAR_ErrorStack::push (int $code [, string $level = 'error' [, array $params = array() [, string $msg = FALSE [, array $repackage = FALSE [, array $backtrace = FALSE]]]]]) where it looks like $code needs to be an int. Also under the methos @params it says int. I substituted 1 for the message "MYPACKAGE_ERROR_TEST" in the first argument of the call and everything worked fine. I think that the documentation needs to be changed or else something internally is not quite right (in ErrorStack or in php5). Is it possible that php5 is more strict than 4.3.x or is there a way to override/change the $code definition. I guess that a substitution of the errors['code'] could be done using the setErrorMessageTemplate or after passing the array back to the getErrors call (or somewhere else). Or perhaps I'm completely confused here. Any further ideas/comments?
 [2004-05-20 20:41 UTC] jon dot bertsch at ucop dot edu
OK - I found a workaround for this along the lines I mentioned earlier. If you are adding error messages as you go without the setErrorMessageTemplate method, then make the first argument zero (in php5). When calling the errors (I used the getErrors() method) the last argument in the push call shows the error information as expected. e.g: $dsn = array('phptype' => 'mysql', 'hostspec'=> 'localhost', 'database' =>'test','username' => 'user', 'password' => 'pass'); $stack = &PEAR_ErrorStack::singleton('MyPackage'); $stack -> push(0, 'error', array('query' => $query, 'dsn' => $dsn), 'Database error - unable to connect using dsn - %dsn%'); $error_list = $stack -> getErrors(); $my_error = $error_list[0]['message']; //or use a loop for multiple ones If you use the setErrorMessgeTemplate method then: //1. define some vars as in: define('ERROR_ONE',1); define('ERROR_TWO',2); //2. set up the message array $messages = array ( ERROR_ONE=>'Database error - no connection (DSN = %dsn%)', ERROR_TWO =>'Error in Query - %query%'); //push the error to the stack $stack -> push(ERROR_ONE, 'error', array('query' => $query, 'dsn' => $dsn)); You can then get it out the same way as above. I'm sure there's a better way but I haven't been able to get around all the methods yet. By the way in the PEAR.php at lines 782-784 there's the following eval: if ($this->mode & PEAR_ERROR_EXCEPTION) { trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_ErrorStack for exceptions", E_USER_WARNING); eval('$e = new Exception($this->message, $this->code);$e->PEAR_Error = $this;throw($e);'); } Maybe that's the eval you were suggesting. I tested both the use of the zero and the defines with setErrorMessgeTemplate method on php4.3.2 and 5.0RC2 and there were no errors and the error message(s) were as expected with the %token% correctly replaced. have not tried other pieces of this class.
 [2004-05-21 02:21 UTC] cellog
The basic problem is that the MYPACKAGE_ERROR_TEST constant is not defined in the code you showed. Therefore, the expression MYPACKAGE_ERROR_TEST is converted into the string "MYPACKAGE_ERROR_TEST," which would generate an E_NOTICE if you had error_reporting set to E_ALL. Add the line: define('MYPACKAGE_ERROR_TEST', 1); to the top of the example, and it will work as expected. I'll add in basic type checking so that it can avoid that kind of mistake. Greg
 [2004-05-21 03:23 UTC] cellog
This bug has been fixed in CVS. In case this was a documentation problem, the fix will show up at the end of next Sunday (CET) on pear.php.net. In case this was a pear.php.net website problem, the change will show up on the website in short time. Thank you for the report, and for helping us make PEAR better. This will be fixed in the next release
 [2004-05-21 13:37 UTC] jon dot bertsch at ucop dot edu
Two things - first the documentation doesn't say that one needs to define error codes - it implies this is an option - you can define it in the call to the push method, or create the definitions and send an array with the meanings. The example I posted is essentially identical to the documentation and there were no defined options in the example under the sectionat the end of the introduction section under changing calls from PEAR::raiseError(). Second - this still doesn't explain why it works correctly in php 4.3.x and not in php 5 (RC2). I just wonder what's different.