summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSara Golemon <pollita@php.net>2017-03-23 12:27:33 -0700
committerSara Golemon <pollita@php.net>2017-03-23 13:31:06 -0700
commit0fb640c71763ddb1b8017c87cec10fc76764feff (patch)
tree1e9245d9f854b1be2afaae6fb3270955780fe0fa
parent1517fdb36cc125ffedd52e6e00cd3bb1adefd210 (diff)
downloadphp-git-0fb640c71763ddb1b8017c87cec10fc76764feff.tar.gz
Fix bug where `yield from` is captured too greedily
In the following piece of code: ```php function from1234($x) { return $x; } function foo($x) { yield from1234($x); } ``` The statement inside foo is taken as `yield from` `1234($x)` which is neither the intent, nor even legal syntax for an fcall. Do a lookahead for breaking non-label characters after the `yield from` and only accept it if they occur.
-rw-r--r--NEWS1
-rw-r--r--Zend/tests/generators/yield_from_greedy_parse.phpt24
-rw-r--r--Zend/zend_language_scanner.l3
3 files changed, 27 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index f2f392c791..f82f68cb91 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ PHP NEWS
referenced return). (Nikita)
. Fixed bug #74265 (Build problems after 7.0.17 release: undefined reference
to `isfinite'). (Nikita)
+ . Fixed bug #74302 (yield fromLABEL is over-greedy). (Sara)
- Date:
. Fixed bug #72096 (Swatch time value incorrect for dates before 1970). (mcq8)
diff --git a/Zend/tests/generators/yield_from_greedy_parse.phpt b/Zend/tests/generators/yield_from_greedy_parse.phpt
new file mode 100644
index 0000000000..598fb515b4
--- /dev/null
+++ b/Zend/tests/generators/yield_from_greedy_parse.phpt
@@ -0,0 +1,24 @@
+--TEST--
+yield from parses too greedily
+--FILE--
+<?php
+
+function from1234($x) {
+ return $x;
+}
+
+function bar() {
+ yield 24;
+}
+
+function foo() {
+ yield from1234(42);
+ yield from(bar());
+}
+
+foreach (foo() as $value) {
+ var_dump($value);
+}
+--EXPECT--
+int(42)
+int(24)
diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l
index 63f4bc15c4..093d7de9aa 100644
--- a/Zend/zend_language_scanner.l
+++ b/Zend/zend_language_scanner.l
@@ -1155,7 +1155,8 @@ NEWLINE ("\r"|"\n"|"\r\n")
RETURN_TOKEN(T_RETURN);
}
-<ST_IN_SCRIPTING>"yield"{WHITESPACE}"from" {
+<ST_IN_SCRIPTING>"yield"{WHITESPACE}"from"[^a-zA-Z0-9_\x80-\xff] {
+ yyless(--yyleng);
HANDLE_NEWLINES(yytext, yyleng);
RETURN_TOKEN(T_YIELD_FROM);
}