]> granicus.if.org Git - php/commitdiff
Fixed bug #31158 (array_splice on $GLOBALS crashes)
authorDmitry Stogov <dmitry@php.net>
Mon, 4 Jul 2005 10:01:10 +0000 (10:01 +0000)
committerDmitry Stogov <dmitry@php.net>
Mon, 4 Jul 2005 10:01:10 +0000 (10:01 +0000)
NEWS
Zend/zend_API.h
Zend/zend_execute_API.c
ext/standard/array.c
ext/standard/tests/array/bug31158.phpt [new file with mode: 0755]

diff --git a/NEWS b/NEWS
index 95e13432b76f87d2d8426c42bd3b4ac3cf39fc1a..11806fd223b4d9665957f8b9d7ffc52f9e7376dc 100644 (file)
--- 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)
index 2a967fd60287999241705884eb6648f6116c5e95..33f8eeb870032ba0562f574eda963711aa0a36b4 100644 (file)
@@ -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);
index 1ff2f99126cc0970504b6888085c39482e4b7397..5272718ddc90de27aeedd662087e8aef10a3c946 100644 (file)
@@ -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;
index 55ccaf576e1b7a5c82a582505c2728a9a7b3acf0..c14953711d6782f614815c0c069c497386ea15e2 100644 (file)
@@ -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 (executable)
index 0000000..e672a10
--- /dev/null
@@ -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
+