]> granicus.if.org Git - php/commitdiff
Fix crash when exception occurs during nested rope
authorNikita Popov <nikic@php.net>
Mon, 6 Jul 2015 18:53:54 +0000 (20:53 +0200)
committerNikita Popov <nikic@php.net>
Mon, 6 Jul 2015 18:53:54 +0000 (20:53 +0200)
Adds extra condition that the rope var of INIT/ADD must match the
one one END.

Zend/tests/exception_in_nested_rope.phpt [new file with mode: 0644]
Zend/zend_execute.c

diff --git a/Zend/tests/exception_in_nested_rope.phpt b/Zend/tests/exception_in_nested_rope.phpt
new file mode 100644 (file)
index 0000000..df0d6fb
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+Exception during nested rope
+--FILE--
+<?php
+
+set_error_handler(function() { throw new Exception; });
+
+try {
+    $a = "foo";
+    $str = "$a${"y$a$a"}y";
+} catch (Exception $e) {
+    echo "Exception\n";
+}
+
+?>
+--EXPECT--
+Exception
index 88d0135cfcc7b628d3da40327e8fa4e0b9782e2c..6122566b3e64a902a694e95ce61ce71594645b2b 100644 (file)
@@ -2522,7 +2522,8 @@ static zend_always_inline void i_cleanup_unfinished_execution(zend_execute_data
                                } else if (brk_opline->opcode == ZEND_ROPE_END) {
                                        zend_string **rope = (zend_string **) EX_VAR(brk_opline->op1.var);
                                        zend_op *last = EX(func)->op_array.opcodes + op_num;
-                                       while (last->opcode != ZEND_ROPE_ADD && last->opcode != ZEND_ROPE_INIT) {
+                                       while ((last->opcode != ZEND_ROPE_ADD && last->opcode != ZEND_ROPE_INIT)
+                                                       || last->result.var != brk_opline->op1.var) {
                                                ZEND_ASSERT(last >= EX(func)->op_array.opcodes);
                                                last--;
                                        }