diff options
| author | Sara Golemon <pollita@php.net> | 2017-03-23 12:27:33 -0700 |
|---|---|---|
| committer | Sara Golemon <pollita@php.net> | 2017-03-23 13:31:06 -0700 |
| commit | 0fb640c71763ddb1b8017c87cec10fc76764feff (patch) | |
| tree | 1e9245d9f854b1be2afaae6fb3270955780fe0fa | |
| parent | 1517fdb36cc125ffedd52e6e00cd3bb1adefd210 (diff) | |
| download | php-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-- | NEWS | 1 | ||||
| -rw-r--r-- | Zend/tests/generators/yield_from_greedy_parse.phpt | 24 | ||||
| -rw-r--r-- | Zend/zend_language_scanner.l | 3 |
3 files changed, 27 insertions, 1 deletions
@@ -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); } |
