]> granicus.if.org Git - php/commitdiff
Fix bug #70662
authorNikita Popov <nikic@php.net>
Wed, 7 Oct 2015 20:47:09 +0000 (22:47 +0200)
committerNikita Popov <nikic@php.net>
Thu, 8 Oct 2015 09:03:39 +0000 (11:03 +0200)
This replaces add_new with update for the RW case. This should not
be problematic for performance, as this branch throws a notice.

Alternatively add_new could also be replaced with add. I went with
update, because it makes $a[0] += 1 behavior the same as
$a[0] = $a[0] + 1.

NEWS
Zend/tests/bug70662.phpt [new file with mode: 0644]
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index 1bfcfffbae873ded92c9797af03e9d45e816a24f..fcc1552ff39a12b553d5fdc801acb9373a7bc0df 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 15 Oct 2015, PHP 7.0.0 RC 5
 
+- Core:
+  . Fixed bug #70662 (Duplicate array key via undefined index error handler).
+    (Nikita)
+
 - Mcrypt:
   . Fixed bug #70625 (mcrypt_encrypt() won't return data when no IV was
     specified under RC4). (Nikita)
diff --git a/Zend/tests/bug70662.phpt b/Zend/tests/bug70662.phpt
new file mode 100644 (file)
index 0000000..2bda814
--- /dev/null
@@ -0,0 +1,18 @@
+--TEST--
+Bug #70662: Duplicate array key via undefined index error handler
+--FILE--
+<?php
+
+$a = [];
+set_error_handler(function() use(&$a) {
+    $a['b'] = 2;
+});
+$a['b'] += 1;
+var_dump($a);
+
+?>
+--EXPECT--
+array(1) {
+  ["b"]=>
+  int(1)
+}
index f88ccb1ea7021d6ba79b32619aad6134184c6704..5b98fb47fb09e586748004a0dc47490609abae93 100644 (file)
@@ -1557,7 +1557,8 @@ num_index:
                                        break;
                                case BP_VAR_RW:
                                        zend_error(E_NOTICE,"Undefined offset: " ZEND_LONG_FMT, hval);
-                                       /* break missing intentionally */
+                                       retval = zend_hash_index_update(ht, hval, &EG(uninitialized_zval));
+                                       break;
                                case BP_VAR_W:
                                        retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval));
                                        break;
@@ -1605,7 +1606,8 @@ str_index:
                                        break;
                                case BP_VAR_RW:
                                        zend_error(E_NOTICE,"Undefined index: %s", ZSTR_VAL(offset_key));
-                                       /* break missing intentionally */
+                                       retval = zend_hash_update(ht, offset_key, &EG(uninitialized_zval));
+                                       break;
                                case BP_VAR_W:
                                        retval = zend_hash_add_new(ht, offset_key, &EG(uninitialized_zval));
                                        break;
index f0e7278459f7b5d2ed008cb726798416306969dc..0c34f1717bc7bbe4ed1bcd64949110d96ac2df8e 100644 (file)
@@ -1565,7 +1565,8 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|V
                                        break;
                                case BP_VAR_RW:
                                        zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
-                                       /* break missing intentionally */
+                                       retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
+                                       break;
                                case BP_VAR_W:
                                        retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
                                        break;
index 035f4ab7af0d5784d855c524d1042bb4a6951145..031e234281b46534a5f5da3ffc19cee1954db4d6 100644 (file)
@@ -5024,7 +5024,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
                                        break;
                                case BP_VAR_RW:
                                        zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
-                                       /* break missing intentionally */
+                                       retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
+                                       break;
                                case BP_VAR_W:
                                        retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
                                        break;
@@ -6945,7 +6946,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
                                        break;
                                case BP_VAR_RW:
                                        zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
-                                       /* break missing intentionally */
+                                       retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
+                                       break;
                                case BP_VAR_W:
                                        retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
                                        break;
@@ -7441,7 +7443,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
                                        break;
                                case BP_VAR_RW:
                                        zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
-                                       /* break missing intentionally */
+                                       retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
+                                       break;
                                case BP_VAR_W:
                                        retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
                                        break;
@@ -31092,7 +31095,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
                                        break;
                                case BP_VAR_RW:
                                        zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
-                                       /* break missing intentionally */
+                                       retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
+                                       break;
                                case BP_VAR_W:
                                        retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
                                        break;
@@ -33305,7 +33309,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
                                        break;
                                case BP_VAR_RW:
                                        zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
-                                       /* break missing intentionally */
+                                       retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
+                                       break;
                                case BP_VAR_W:
                                        retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
                                        break;
@@ -34242,7 +34247,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
                                        break;
                                case BP_VAR_RW:
                                        zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
-                                       /* break missing intentionally */
+                                       retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
+                                       break;
                                case BP_VAR_W:
                                        retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
                                        break;
@@ -41434,7 +41440,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
                                        break;
                                case BP_VAR_RW:
                                        zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
-                                       /* break missing intentionally */
+                                       retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
+                                       break;
                                case BP_VAR_W:
                                        retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
                                        break;
@@ -42415,7 +42422,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
                                        break;
                                case BP_VAR_RW:
                                        zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
-                                       /* break missing intentionally */
+                                       retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
+                                       break;
                                case BP_VAR_W:
                                        retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
                                        break;
@@ -42816,7 +42824,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
                                        break;
                                case BP_VAR_RW:
                                        zend_error(E_NOTICE,"Undefined variable: %s", ZSTR_VAL(name));
-                                       /* break missing intentionally */
+                                       retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
+                                       break;
                                case BP_VAR_W:
                                        retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval));
                                        break;