summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2005-07-04 10:01:10 +0000
committerDmitry Stogov <dmitry@php.net>2005-07-04 10:01:10 +0000
commit1d33a3e95e4e23188ca7fb4d289a96d1fa4be50e (patch)
tree2f370468d0bca7f4bbab7f679e975e03925e4429
parent43210250eaeb5139d867ba848b87173946e6e5fe (diff)
downloadphp-git-1d33a3e95e4e23188ca7fb4d289a96d1fa4be50e.tar.gz
Fixed bug #31158 (array_splice on $GLOBALS crashes)
-rw-r--r--NEWS1
-rw-r--r--Zend/zend_API.h2
-rw-r--r--Zend/zend_execute_API.c14
-rw-r--r--ext/standard/array.c21
-rwxr-xr-xext/standard/tests/array/bug31158.phpt17
5 files changed, 49 insertions, 6 deletions
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--
+<?php
+function __(){
+ $GLOBALS['a'] = "bug\n";
+ array_splice($GLOBALS,0,count($GLOBALS));
+ /* All global variables including $GLOBALS are removed */
+ echo $GLOBALS['a'];
+}
+__();
+echo "ok\n";
+?>
+--EXPECTF--
+Notice: Undefined variable: GLOBALS in %sbug31158.php on line 6
+ok
+