From 1d33a3e95e4e23188ca7fb4d289a96d1fa4be50e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 4 Jul 2005 10:01:10 +0000 Subject: [PATCH] Fixed bug #31158 (array_splice on $GLOBALS crashes) --- NEWS | 1 + Zend/zend_API.h | 2 ++ Zend/zend_execute_API.c | 14 ++++++++++++++ ext/standard/array.c | 21 +++++++++++++++------ ext/standard/tests/array/bug31158.phpt | 17 +++++++++++++++++ 5 files changed, 49 insertions(+), 6 deletions(-) create mode 100755 ext/standard/tests/array/bug31158.phpt diff --git a/NEWS b/NEWS index 95e13432b7..11806fd223 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,7 @@ PHP NEWS overloaded (__get)). (Dmitry) - Fixed bug #31358 (Older GCC versions do not provide portable va_copy()). (Jani) +- Fixed bug #31158 (array_splice on $GLOBALS crashes). (Dmitry) - Fixed bug #30828 (debug_backtrace() reports incorrect class in overridden methods). (Dmitry) - Fixed bug #30519 (Interface not existing says Class not found). (Dmitry) diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 2a967fd602..33f8eeb870 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -352,6 +352,8 @@ ZEND_API int zend_set_hash_symbol(zval *symbol, char *name, int name_length, ZEND_API int zend_delete_global_variable(char *name, int name_len TSRMLS_DC); +ZEND_API void zend_reset_all_cv(HashTable *symbol_table TSRMLS_DC); + #define add_method(arg, key, method) add_assoc_function((arg), (key), (method)) ZEND_API ZEND_FUNCTION(display_disabled_function); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 1ff2f99126..5272718ddc 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1384,6 +1384,20 @@ void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC) } } +ZEND_API void zend_reset_all_cv(HashTable *symbol_table TSRMLS_DC) +{ + zend_execute_data *ex; + int i; + + for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) { + if (ex->symbol_table == symbol_table) { + for (i = 0; i < ex->op_array->last_var; i++) { + ex->CVs[i] = NULL; + } + } + } +} + ZEND_API int zend_delete_global_variable(char *name, int name_len TSRMLS_DC) { zend_execute_data *ex; diff --git a/ext/standard/array.c b/ext/standard/array.c index 55ccaf576e..c14953711d 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -2060,8 +2060,11 @@ PHP_FUNCTION(array_unshift) hashtable and replace it with new one */ new_hash = php_splice(Z_ARRVAL_P(stack), 0, 0, &args[1], argc-1, NULL); zend_hash_destroy(Z_ARRVAL_P(stack)); - FREE_HASHTABLE(Z_ARRVAL_P(stack)); - Z_ARRVAL_P(stack) = new_hash; + if (Z_ARRVAL_P(stack) == &EG(symbol_table)) { + zend_reset_all_cv(&EG(symbol_table) TSRMLS_CC); + } + *Z_ARRVAL_P(stack) = *new_hash; + FREE_HASHTABLE(new_hash); /* Clean up and return the number of elements in the stack */ efree(args); @@ -2137,8 +2140,11 @@ PHP_FUNCTION(array_splice) /* Replace input array's hashtable with the new one */ zend_hash_destroy(Z_ARRVAL_P(array)); - efree(Z_ARRVAL_P(array)); - Z_ARRVAL_P(array) = new_hash; + if (Z_ARRVAL_P(array) == &EG(symbol_table)) { + zend_reset_all_cv(&EG(symbol_table) TSRMLS_CC); + } + *Z_ARRVAL_P(array) = *new_hash; + FREE_HASHTABLE(new_hash); /* Clean up */ if (argc == 4) @@ -2670,8 +2676,11 @@ PHP_FUNCTION(array_pad) /* Copy the result hash into return value */ zend_hash_destroy(Z_ARRVAL_P(return_value)); - efree(Z_ARRVAL_P(return_value)); - Z_ARRVAL_P(return_value) = new_hash; + if (Z_ARRVAL_P(return_value) == &EG(symbol_table)) { + zend_reset_all_cv(&EG(symbol_table) TSRMLS_CC); + } + *Z_ARRVAL_P(return_value) = *new_hash; + FREE_HASHTABLE(new_hash); /* Clean up */ efree(pads); diff --git a/ext/standard/tests/array/bug31158.phpt b/ext/standard/tests/array/bug31158.phpt new file mode 100755 index 0000000000..e672a10b28 --- /dev/null +++ b/ext/standard/tests/array/bug31158.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #31158 (array_splice on $GLOBALS crashes) +--FILE-- + +--EXPECTF-- +Notice: Undefined variable: GLOBALS in %sbug31158.php on line 6 +ok + -- 2.50.1