summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/bug79793.phpt32
-rw-r--r--Zend/zend_execute.c7
3 files changed, 40 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index bfe7b596eb..6c35059e5e 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,8 @@ PHP NEWS
(Nikita)
. Fixed bug #79784 (Use after free if changing array during undef var during
array write fetch). (Nikita)
+ . Fixed bug #79793 (Use after free if string used in undefined index warning
+ is changed). (Nikita)
- Fileinfo:
. Fixed bug #79756 (finfo_file crash (FILEINFO_MIME)). (cmb)
diff --git a/Zend/tests/bug79793.phpt b/Zend/tests/bug79793.phpt
new file mode 100644
index 0000000000..9e4e2e20be
--- /dev/null
+++ b/Zend/tests/bug79793.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Bug #79793: Use after free if string used in undefined index warning is changed
+--FILE--
+<?php
+
+$key = "foo";
+$key .= "bar";
+set_error_handler(function($_, $m) use (&$key) {
+ echo "$m\n";
+ $key .= "baz";
+});
+
+$ary = [];
+$ary[$key]++;
+var_dump($ary);
+$ary[$key] += 1;
+var_dump($ary);
+
+?>
+--EXPECT--
+Undefined index: foobar
+array(1) {
+ ["foobar"]=>
+ int(1)
+}
+Undefined index: foobarbaz
+array(2) {
+ ["foobar"]=>
+ int(1)
+ ["foobarbaz"]=>
+ int(1)
+}
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 5aed92ff45..59c151fe66 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -2181,10 +2181,15 @@ str_index:
retval = &EG(uninitialized_zval);
break;
case BP_VAR_RW:
+ /* Key may be released while throwing the undefined index warning. */
+ zend_string_addref(offset_key);
if (UNEXPECTED(zend_undefined_index_write(ht, offset_key) == FAILURE)) {
+ zend_string_release(offset_key);
return NULL;
}
- /* break missing intentionally */
+ retval = zend_hash_add_new(ht, offset_key, &EG(uninitialized_zval));
+ zend_string_release(offset_key);
+ break;
case BP_VAR_W:
retval = zend_hash_add_new(ht, offset_key, &EG(uninitialized_zval));
break;