From 0d7d9b0540f7c28cf0784e4a3a5f93924c336677 Mon Sep 17 00:00:00 2001 From: Etienne Kneuss Date: Sun, 5 Oct 2008 14:20:55 +0000 Subject: [PATCH] Fix #46222 (Allow indirect modifications of Arrays inside ArrayObject + fix EG(uninitialized_zval_ptr) overwrite) --- NEWS | 2 ++ ext/spl/spl_array.c | 29 +++++++++++++++++++++++------ ext/spl/tests/array_026.phpt | 24 ++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 ext/spl/tests/array_026.phpt diff --git a/NEWS b/NEWS index 38470182ea..d622506984 100644 --- 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. diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 90d46859e3..cade73f63a 100755 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -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 index 0000000000..9c79c57b66 --- /dev/null +++ b/ext/spl/tests/array_026.phpt @@ -0,0 +1,24 @@ +--TEST-- +SPL: ArrayObject indirect offsetGet overwriting EG(uninitialized_zvar_ptr) +--FILE-- + +--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 -- 2.40.0