]> granicus.if.org Git - php/commitdiff
initialize retval_ptr_ptr before returning FAILURE
authorAntony Dovgal <tony2001@php.net>
Fri, 27 Apr 2007 08:11:37 +0000 (08:11 +0000)
committerAntony Dovgal <tony2001@php.net>
Fri, 27 Apr 2007 08:11:37 +0000 (08:11 +0000)
this fixes invalid read in #41209

Zend/tests/bug41209.phpt [new file with mode: 0644]
Zend/zend_execute_API.c

diff --git a/Zend/tests/bug41209.phpt b/Zend/tests/bug41209.phpt
new file mode 100644 (file)
index 0000000..0834b37
--- /dev/null
@@ -0,0 +1,46 @@
+--TEST--
+Bug #41209 (Segmentation fault with ArrayAccess, set_error_handler and undefined var)
+--FILE--
+<?php
+
+class env
+{
+    public function __construct()
+    {
+        set_error_handler(array(__CLASS__, 'errorHandler'));
+    }
+
+    public static function errorHandler($errno, $errstr, $errfile, $errline)
+    {
+        throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
+    }
+}
+
+class cache implements ArrayAccess
+{
+    private $container = array();
+
+    public function offsetGet($id) {}
+
+    public function offsetSet($id, $value) {}
+
+    public function offsetUnset($id) {}
+
+    public function offsetExists($id)
+    {
+        return isset($this->containers[(string) $id]);
+    }
+}
+
+$env = new env();
+$cache = new cache();
+var_dump(isset($cache[$id]));
+
+echo "Done\n";
+?>
+--EXPECTF--    
+Fatal error: Uncaught exception 'ErrorException' with message 'Undefined variable: id' in %s:%d
+Stack trace:
+#0 %s(%d): env::errorHandler()
+#1 {main}
+  thrown in %s on line %d
index 5e3bd2922698c9a0c62771b4624f03fbe4227e7c..a8d9ef42b79b19c48c4e57617cd18909437b1031 100644 (file)
@@ -658,6 +658,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
        int fname_len;
        zstr colon, fname, lcname;
 
+       *fci->retval_ptr_ptr = NULL;
+
        if (!EG(active)) {
                return FAILURE; /* executor is already inactive */
        }
@@ -688,11 +690,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                memset(&execute_data, 0, sizeof(zend_execute_data));
        }
 
-       /* we may return SUCCESS, and yet retval may be uninitialized,
-        * if there was an exception...
-        */
-       *fci->retval_ptr_ptr = NULL;
-
        if (!fci_cache || !fci_cache->initialized) {
                if (Z_TYPE_P(fci->function_name)==IS_ARRAY) { /* assume array($obj, $name) couple */
                        zval **tmp_object_ptr, **tmp_real_function_name;