]> granicus.if.org Git - php/commitdiff
Fixed bug #40833 (Crash when using unset() on an ArrayAccess object retrieved via...
authorDmitry Stogov <dmitry@php.net>
Mon, 19 Mar 2007 18:31:30 +0000 (18:31 +0000)
committerDmitry Stogov <dmitry@php.net>
Mon, 19 Mar 2007 18:31:30 +0000 (18:31 +0000)
NEWS
Zend/tests/bug40833.phpt [new file with mode: 0755]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index 4609f7c88dc1b6c53609958a5a0863e7e4a2345a..766c9b44b0b068f05766c4d7de65fa46783d50ab 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,8 @@ PHP                                                                        NEWS
 - Fixed CVE-2007-1001, GD wbmp used with invalid image size (Pierre)
 - Fixed bug #40848 (sorting issue on 64-bit Solaris). (Wez)
 - Fixed bug #40836 (Segfault in ext/dom). (Rob)
+- Fixed bug #40833 (Crash when using unset() on an ArrayAccess object retrieved
+  via __get()). (Dmitry)
 - Fixed bug #40815 (using strings like "class::func" and static methods in 
   set_exception_handler() might result in crash). (Tony)
 - Fixed bug #40805 (Failure executing function ibase_execute()). (Tony)
diff --git a/Zend/tests/bug40833.phpt b/Zend/tests/bug40833.phpt
new file mode 100755 (executable)
index 0000000..c56ca4c
--- /dev/null
@@ -0,0 +1,72 @@
+--TEST--
+Bug #40833 (Crash when using unset() on an ArrayAccess object retrieved via __get) 
+--FILE--
+<?php
+       class entity
+       {
+               private $data;
+               private $modified;
+
+               function __get($name)
+               {
+                       if ( isset($this->data[$name]) )
+                               return $this->data[$name];
+                       else
+                               return $this->data[$name] = new set($this);
+               }
+
+               function __set($name, $value)
+               {
+                       $this->modified[$name] = $value;
+               }
+       }
+
+       class set implements ArrayAccess
+       {
+               private $entity;
+
+               function __construct($entity)
+               {
+                       $this->entity = $entity;
+                       $this->entity->whatever = $this;
+               }
+
+               function clear() {
+                       $this->entity->whatever = null;
+               }
+
+               function offsetUnset($offset)
+               {
+                       $this->clear();
+//                     $this->entity->{$this->name} = null;
+               }
+
+               function offsetSet($offset, $value)
+               {
+               }
+
+               function offsetGet($offset)
+               {
+                       return 'Bogus ';
+               }
+
+               function offsetExists($offset)
+               {
+               }
+       }
+
+       $entity = new entity();
+       echo($entity->whatever[0]);
+
+       //This will crash
+//     $entity->whatever->clear();
+       unset($entity->whatever[0]);
+
+       //This will not crash (comment previous & uncomment this to test
+//     $test = $entity->whatever; unset($test[0]);
+
+       echo($entity->whatever[0]);
+       echo "ok\n";
+?>
+--EXPECT--
+Bogus Bogus ok
index 6bff73987c55aeba6e6072796c5c5df07d96c948..bad088a2d7fd500908864e1a99bb2dbccf4e6cfd 100644 (file)
@@ -1328,7 +1328,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
        if (IS_OP2_TMP_FREE()) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_R TSRMLS_CC);
+       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
        if (IS_OP2_TMP_FREE()) {
                zval_ptr_dtor(&property);
        } else {
index 7ef731e2c78c73d295a6e56390ca95948e666fda..d64f9f4ee97c25aff882892cd3d3c0225dc21368 100644 (file)
@@ -9185,7 +9185,7 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        if (0) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_R TSRMLS_CC);
+       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
        if (0) {
                zval_ptr_dtor(&property);
        } else {
@@ -10670,7 +10670,7 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        if (1) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_R TSRMLS_CC);
+       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
        if (1) {
                zval_ptr_dtor(&property);
        } else {
@@ -12158,7 +12158,7 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        if (0) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_R TSRMLS_CC);
+       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
        if (0) {
                zval_ptr_dtor(&property);
        } else {
@@ -14118,7 +14118,7 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        if (0) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_R TSRMLS_CC);
+       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
        if (0) {
                zval_ptr_dtor(&property);
        } else {
@@ -15358,7 +15358,7 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
        if (0) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_R TSRMLS_CC);
+       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
        if (0) {
                zval_ptr_dtor(&property);
        } else {
@@ -16362,7 +16362,7 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
        if (1) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_R TSRMLS_CC);
+       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
        if (1) {
                zval_ptr_dtor(&property);
        } else {
@@ -17326,7 +17326,7 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
        if (0) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_R TSRMLS_CC);
+       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
        if (0) {
                zval_ptr_dtor(&property);
        } else {
@@ -18555,7 +18555,7 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        if (0) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_R TSRMLS_CC);
+       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
        if (0) {
                zval_ptr_dtor(&property);
        } else {
@@ -21096,7 +21096,7 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        if (0) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_R TSRMLS_CC);
+       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
        if (0) {
                zval_ptr_dtor(&property);
        } else {
@@ -22573,7 +22573,7 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        if (1) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_R TSRMLS_CC);
+       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
        if (1) {
                zval_ptr_dtor(&property);
        } else {
@@ -24053,7 +24053,7 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        if (0) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_R TSRMLS_CC);
+       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
        if (0) {
                zval_ptr_dtor(&property);
        } else {
@@ -26003,7 +26003,7 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        if (0) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_R TSRMLS_CC);
+       zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC);
        if (0) {
                zval_ptr_dtor(&property);
        } else {