]> granicus.if.org Git - php/commitdiff
Fix #46222 (Allow indirect modifications of Arrays inside ArrayObject + fix EG(uninit...
authorEtienne Kneuss <colder@php.net>
Sun, 5 Oct 2008 14:20:55 +0000 (14:20 +0000)
committerEtienne Kneuss <colder@php.net>
Sun, 5 Oct 2008 14:20:55 +0000 (14:20 +0000)
NEWS
ext/spl/spl_array.c
ext/spl/tests/array_026.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 38470182ea194b6653583defed230c5a2235bfeb..d622506984c37dc841ee732e865901c19cdd7225 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -45,6 +45,8 @@ PHP                                                                        NEWS
   (vnegrier at optilian dot com, Ilia)
 - Fixed bug #46192 (ArrayObject with objects as storage serialization).
   (Etienne)
+- Fixed bug #46222 (ArrayObject EG(uninitialized_var_ptr) overwrite).
+  (Etienne)
 
 02 Sep 2008, PHP 5.3.0 Alpha 2
 - Removed special treatment of "/tmp" in sessions for open_basedir.
index 90d46859e3aaca72d7317e088ddf53f471fc758e..cade73f63ab1441c89e4396bec41cd760b1e91c0 100755 (executable)
@@ -281,6 +281,7 @@ static zval **spl_array_get_dimension_ptr_ptr(int check_inherited, zval *object,
        spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
        zval **retval;
        long index;
+       HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
 
 /*  We cannot get the pointer pointer so we don't allow it here for now
        if (check_inherited && intern->fptr_offset_get) {
@@ -293,9 +294,17 @@ static zval **spl_array_get_dimension_ptr_ptr(int check_inherited, zval *object,
        
        switch(Z_TYPE_P(offset)) {
        case IS_STRING:
-               if (zend_symtable_find(spl_array_get_hash_table(intern, 0 TSRMLS_CC), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **) &retval) == FAILURE) {
-                       zend_error(E_NOTICE, "Undefined index:  %s", Z_STRVAL_P(offset));
-                       return &EG(uninitialized_zval_ptr);
+               if (zend_symtable_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **) &retval) == FAILURE) {
+                       if (type == BP_VAR_W || type == BP_VAR_RW) {
+                               zval *value;
+                               ALLOC_INIT_ZVAL(value);
+                               zend_symtable_update(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void**)&value, sizeof(void*), NULL);
+                               zend_symtable_find(ht, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **) &retval);
+                               return retval;
+                       } else {
+                               zend_error(E_NOTICE, "Undefined index:  %s", Z_STRVAL_P(offset));
+                               return &EG(uninitialized_zval_ptr);
+                       }
                } else {
                        return retval;
                }
@@ -308,9 +317,17 @@ static zval **spl_array_get_dimension_ptr_ptr(int check_inherited, zval *object,
                } else {
                        index = Z_LVAL_P(offset);
                }
-               if (zend_hash_index_find(spl_array_get_hash_table(intern, 0 TSRMLS_CC), index, (void **) &retval) == FAILURE) {
-                       zend_error(E_NOTICE, "Undefined offset:  %ld", Z_LVAL_P(offset));
-                       return &EG(uninitialized_zval_ptr);
+               if (zend_hash_index_find(ht, index, (void **) &retval) == FAILURE) {
+                       if (type == BP_VAR_W || type == BP_VAR_RW) {
+                               zval *value;
+                               ALLOC_INIT_ZVAL(value);
+                               zend_hash_index_update(ht, index, (void**)&value, sizeof(void*), NULL);
+                               zend_hash_index_find(ht, index, (void **) &retval);
+                               return retval;
+                       } else {
+                               zend_error(E_NOTICE, "Undefined offset:  %ld", Z_LVAL_P(offset));
+                               return &EG(uninitialized_zval_ptr);
+                       }
                } else {
                        return retval;
                }
diff --git a/ext/spl/tests/array_026.phpt b/ext/spl/tests/array_026.phpt
new file mode 100644 (file)
index 0000000..9c79c57
--- /dev/null
@@ -0,0 +1,24 @@
+--TEST--
+SPL: ArrayObject indirect offsetGet overwriting EG(uninitialized_zvar_ptr)
+--FILE--
+<?php
+$test = new ArrayObject();
+$test['d1']['d2'] = 'hello';
+$test['d1']['d3'] = 'world';
+var_dump($test, $test3['mmmmm']);
+?>
+--EXPECTF--
+Notice: Undefined variable: test3 in %s%earray_026.php on line %d
+object(ArrayObject)#%d (1) {
+  ["storage":"ArrayObject":private]=>
+  array(1) {
+    ["d1"]=>
+    array(2) {
+      ["d2"]=>
+      string(5) "hello"
+      ["d3"]=>
+      string(5) "world"
+    }
+  }
+}
+NULL