diff --git a/ext/tokenizer/LanguageScanner.php b/ext/tokenizer/LanguageScanner.php index dacaf1de6fa..c061baef522 100644 --- a/ext/tokenizer/LanguageScanner.php +++ b/ext/tokenizer/LanguageScanner.php @@ -433,6 +433,14 @@ private function scanVariable(): void return; } + // php-src zend_language_scanner.l: bare '$' when not followed by a variable label start. + if ($this->pos >= $this->len || !$this->isLabelStart($this->source[$this->pos])) { + $this->pos = $start; + $this->pushChar('$'); + ++$this->pos; + + return; + } while ($this->pos < $this->len && $this->isLabelContinue($this->source[$this->pos])) { ++$this->pos; } diff --git a/test/compliance/cases/stdlib/token_get_all_null_byte.phpt b/test/compliance/cases/stdlib/token_get_all_null_byte.phpt new file mode 100644 index 00000000000..38ead1c9f47 --- /dev/null +++ b/test/compliance/cases/stdlib/token_get_all_null_byte.phpt @@ -0,0 +1,12 @@ +--TEST-- +stdlib token_get_all() null byte after $ — literal dollar + T_BAD_CHARACTER (#13896, ext/tokenizer/tokenizer.c) +--FILE-- + +--EXPECT-- +dollar +bad_char diff --git a/test/repro/maintainer_gap_token_get_all_null_byte.php b/test/repro/maintainer_gap_token_get_all_null_byte.php new file mode 100644 index 00000000000..2eb1b22dd44 --- /dev/null +++ b/test/repro/maintainer_gap_token_get_all_null_byte.php @@ -0,0 +1,21 @@ +returnVar->toString()); } + public function test_issue_13896_null_byte_after_dollar(): void + { + $src = "