summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2015-07-06 20:53:54 +0200
committerNikita Popov <nikic@php.net>2015-07-06 20:53:54 +0200
commit724051e3bd0b8618edd1dd3f29f27939efefff08 (patch)
treec70ade764924aa2b5b6d5741409b7a9e38439746
parent89ce8d28dee671eead485077bc97c2b800790d68 (diff)
downloadphp-git-724051e3bd0b8618edd1dd3f29f27939efefff08.tar.gz
Fix crash when exception occurs during nested rope
Adds extra condition that the rope var of INIT/ADD must match the one one END.
-rw-r--r--Zend/tests/exception_in_nested_rope.phpt17
-rw-r--r--Zend/zend_execute.c3
2 files changed, 19 insertions, 1 deletions
diff --git a/Zend/tests/exception_in_nested_rope.phpt b/Zend/tests/exception_in_nested_rope.phpt
new file mode 100644
index 0000000000..df0d6fbf8d
--- /dev/null
+++ b/Zend/tests/exception_in_nested_rope.phpt
@@ -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
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 88d0135cfc..6122566b3e 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -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--;
}