-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Closed
Description
The following combination of arrow function and heredoc will lead to an endless loop:
fn () => <<<HTML
foo
HTML;
Steps to reproduce:
curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar
cat <<EOT >> repro.php
<?php
fn () => <<<HTML
foo
HTML;
EOT
php -l repro.php
No syntax errors detected in repro.php
$ php phpcs.phar -v repro.php
Registering sniffs in the PEAR standard... DONE (28 sniffs registered)
Creating file list... DONE (1 files in queue)
Changing into directory /tmp/repro
Processing repro.php
This will run infinitely.
Full log
This also happens with the current master branch commit 7c406b75a4e53a50aa1eba2d3dda28e3d55f9cfe
.
Following the very verbose output of 7c406b75a4e53a50aa1eba2d3dda28e3d55f9cfe
:
$ ./PHP_CodeSniffer/bin/phpcs -vvv repro.php
Processing ruleset /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/ruleset.xml
Adding sniff files from /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs directory
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/WhiteSpace/ScopeIndentSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/WhiteSpace/ScopeClosingBraceSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/WhiteSpace/ObjectOperatorIndentSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/NamingConventions/ValidVariableNameSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/NamingConventions/ValidFunctionNameSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/NamingConventions/ValidClassNameSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/Functions/ValidDefaultValueSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/Functions/FunctionDeclarationSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/Functions/FunctionCallSignatureSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/Formatting/MultiLineAssignmentSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/Files/IncludingFileSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/ControlStructures/MultiLineConditionSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/ControlStructures/ControlSignatureSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/Commenting/InlineCommentSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/Commenting/FunctionCommentSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/Commenting/FileCommentSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/Commenting/ClassCommentSniff.php
=> /tmp/repro/PHP_CodeSniffer/src/Standards/PEAR/Sniffs/Classes/ClassDeclarationSniff.php
Processing rule "Generic.Functions.FunctionCallArgumentSpacing"
=> /tmp/repro/PHP_CodeSniffer/src/Standards/Generic/Sniffs/Functions/FunctionCallArgumentSpacingSniff.php
Processing rule "Generic.NamingConventions.UpperCaseConstantName"
=> /tmp/repro/PHP_CodeSniffer/src/Standards/Generic/Sniffs/NamingConventions/UpperCaseConstantNameSniff.php
Processing rule "Generic.PHP.LowerCaseConstant"
=> /tmp/repro/PHP_CodeSniffer/src/Standards/Generic/Sniffs/PHP/LowerCaseConstantSniff.php
Processing rule "Generic.PHP.DisallowShortOpenTag"
=> /tmp/repro/PHP_CodeSniffer/src/Standards/Generic/Sniffs/PHP/DisallowShortOpenTagSniff.php
Processing rule "Generic.WhiteSpace.DisallowTabIndent"
=> /tmp/repro/PHP_CodeSniffer/src/Standards/Generic/Sniffs/WhiteSpace/DisallowTabIndentSniff.php
Processing rule "Generic.Commenting.DocComment"
=> /tmp/repro/PHP_CodeSniffer/src/Standards/Generic/Sniffs/Commenting/DocCommentSniff.php
Processing rule "Squiz.Commenting.DocCommentAlignment"
=> /tmp/repro/PHP_CodeSniffer/src/Standards/Squiz/Sniffs/Commenting/DocCommentAlignmentSniff.php
Processing rule "Generic.Files.LineLength"
=> /tmp/repro/PHP_CodeSniffer/src/Standards/Generic/Sniffs/Files/LineLengthSniff.php
=> property "lineLimit" set to "85"
=> property "absoluteLineLimit" set to "0"
Processing rule "Generic.Files.LineEndings"
=> /tmp/repro/PHP_CodeSniffer/src/Standards/Generic/Sniffs/Files/LineEndingsSniff.php
=> property "eolChar" set to "\n"
Processing rule "Generic.Functions.FunctionCallArgumentSpacing.TooMuchSpaceAfterComma"
=> /tmp/repro/PHP_CodeSniffer/src/Standards/Generic/Sniffs/Functions/FunctionCallArgumentSpacingSniff.php
=> severity set to 0
Processing rule "Generic.ControlStructures.InlineControlStructure"
=> /tmp/repro/PHP_CodeSniffer/src/Standards/Generic/Sniffs/ControlStructures/InlineControlStructureSniff.php
=> property "error" set to "false"
=> Ruleset processing complete; included 28 sniffs and excluded 0
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\WhiteSpace\ScopeIndentSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\WhiteSpace\ScopeClosingBraceSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\WhiteSpace\ObjectOperatorIndentSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\NamingConventions\ValidVariableNameSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\NamingConventions\ValidFunctionNameSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\NamingConventions\ValidClassNameSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\Functions\ValidDefaultValueSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\Functions\FunctionDeclarationSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\Functions\FunctionCallSignatureSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\Formatting\MultiLineAssignmentSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\Files\IncludingFileSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\ControlStructures\MultiLineConditionSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\ControlStructures\ControlSignatureSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\Commenting\InlineCommentSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\Commenting\FunctionCommentSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\Commenting\FileCommentSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\Commenting\ClassCommentSniff
Registered PHP_CodeSniffer\Standards\PEAR\Sniffs\Classes\ClassDeclarationSniff
Registered PHP_CodeSniffer\Standards\Generic\Sniffs\Functions\FunctionCallArgumentSpacingSniff
Registered PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\UpperCaseConstantNameSniff
Registered PHP_CodeSniffer\Standards\Generic\Sniffs\PHP\LowerCaseConstantSniff
Registered PHP_CodeSniffer\Standards\Generic\Sniffs\PHP\DisallowShortOpenTagSniff
Registered PHP_CodeSniffer\Standards\Generic\Sniffs\WhiteSpace\DisallowTabIndentSniff
Registered PHP_CodeSniffer\Standards\Generic\Sniffs\Commenting\DocCommentSniff
Registered PHP_CodeSniffer\Standards\Squiz\Sniffs\Commenting\DocCommentAlignmentSniff
Registered PHP_CodeSniffer\Standards\Generic\Sniffs\Files\LineLengthSniff
Registered PHP_CodeSniffer\Standards\Generic\Sniffs\Files\LineEndingsSniff
Registered PHP_CodeSniffer\Standards\Generic\Sniffs\ControlStructures\InlineControlStructureSniff
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token [1]: T_DO => do
Process token [2]: T_WHITESPACE => ·
Process token 3 : T_OPEN_CURLY_BRACKET => {
Process token [4]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token [1]: T_WHITESPACE => ·
Process token [2]: T_WHILE => while
Process token [3]: T_WHITESPACE => ·
Process token 4 : T_OPEN_PARENTHESIS => (
Process token [5]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token 1 : T_SEMICOLON => ;
Process token [2]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token [1]: T_WHILE => while
Process token [2]: T_WHITESPACE => ·
Process token 3 : T_OPEN_PARENTHESIS => (
Process token [4]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token [1]: T_WHITESPACE => ·
Process token 2 : T_OPEN_CURLY_BRACKET => {
Process token [3]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token [1]: T_FOR => for
Process token [2]: T_WHITESPACE => ·
Process token 3 : T_OPEN_PARENTHESIS => (
Process token [4]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token [1]: T_WHITESPACE => ·
Process token 2 : T_OPEN_CURLY_BRACKET => {
Process token [3]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token [1]: T_IF => if
Process token [2]: T_WHITESPACE => ·
Process token 3 : T_OPEN_PARENTHESIS => (
Process token [4]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token [1]: T_WHITESPACE => ·
Process token 2 : T_OPEN_CURLY_BRACKET => {
Process token [3]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token [1]: T_FOREACH => foreach
Process token [2]: T_WHITESPACE => ·
Process token 3 : T_OPEN_PARENTHESIS => (
Process token [4]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token [1]: T_WHITESPACE => ·
Process token 2 : T_OPEN_CURLY_BRACKET => {
Process token [3]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token 1 : T_CLOSE_CURLY_BRACKET => }
Process token [2]: T_WHITESPACE => ·
Process token [3]: T_ELSE => else
Process token [4]: T_WHITESPACE => ·
Process token [5]: T_IF => if
Process token [6]: T_WHITESPACE => ·
Process token 7 : T_OPEN_PARENTHESIS => (
Process token [8]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token [1]: T_WHITESPACE => ·
Process token 2 : T_OPEN_CURLY_BRACKET => {
Process token [3]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token 1 : T_CLOSE_CURLY_BRACKET => }
Process token [2]: T_WHITESPACE => ·
Process token [3]: T_ELSEIF => elseif
Process token [4]: T_WHITESPACE => ·
Process token 5 : T_OPEN_PARENTHESIS => (
Process token [6]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token [1]: T_WHITESPACE => ·
Process token 2 : T_OPEN_CURLY_BRACKET => {
Process token [3]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token 1 : T_CLOSE_CURLY_BRACKET => }
Process token [2]: T_WHITESPACE => ·
Process token [3]: T_ELSE => else
Process token [4]: T_WHITESPACE => ·
Process token 5 : T_OPEN_CURLY_BRACKET => {
Process token [6]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php·
Process token [1]: T_DO => do
Process token [2]: T_WHITESPACE => ·
Process token 3 : T_OPEN_CURLY_BRACKET => {
Process token [4]: T_CLOSE_TAG => ?>
*** END PHP TOKENIZING ***
Creating file list... DONE (1 files in queue)
Changing into directory /tmp/repro
Processing repro.php
*** START PHP TOKENIZING ***
Process token [0]: T_OPEN_TAG => <?php\n
Process token [1]: T_FN => fn
Process token [2]: T_WHITESPACE => ·
Process token 3 : T_OPEN_PARENTHESIS => (
Process token 4 : T_CLOSE_PARENTHESIS => )
Process token [5]: T_WHITESPACE => ·
Process token [6]: T_DOUBLE_ARROW => =>
Process token [7]: T_WHITESPACE => ·
Process token [8]: T_START_HEREDOC => <<<HTML\n
Process token 11 : T_SEMICOLON => ;
Process token [12]: T_WHITESPACE => \n
*** END PHP TOKENIZING ***
*** START TOKEN MAP ***
=> Found unowned parenthesis opener at 3
=> Found unowned parenthesis closer at 4 for 3
*** END TOKEN MAP ***
*** START SCOPE MAP ***
Start scope map at 8:T_START_HEREDOC => <<<HTML\n
=> Begin scope map recursion at token 8 with depth 1
Process token 9 on line 3 [opener:8;]: T_HEREDOC => foo\n
Process token 10 on line 4 [opener:8;]: T_END_HEREDOC => HTML
=> Found scope closer (10:T_END_HEREDOC) for 8:T_START_HEREDOC
*** END SCOPE MAP ***
*** START LEVEL MAP ***
Process token 0 on line 1 [col:1;len:5;lvl:0;]: T_OPEN_TAG => <?php\n
Process token 1 on line 2 [col:1;len:2;lvl:0;]: T_FN => fn
Process token 2 on line 2 [col:3;len:1;lvl:0;]: T_WHITESPACE => ·
Process token 3 on line 2 [col:4;len:1;lvl:0;]: T_OPEN_PARENTHESIS => (
Process token 4 on line 2 [col:5;len:1;lvl:0;]: T_CLOSE_PARENTHESIS => )
Process token 5 on line 2 [col:6;len:1;lvl:0;]: T_WHITESPACE => ·
Process token 6 on line 2 [col:7;len:2;lvl:0;]: T_DOUBLE_ARROW => =>
Process token 7 on line 2 [col:9;len:1;lvl:0;]: T_WHITESPACE => ·
Process token 8 on line 2 [col:10;len:7;lvl:0;]: T_START_HEREDOC => <<<HTML\n
=> Found scope opener for 8:T_START_HEREDOC
* level increased *
* token 8:T_START_HEREDOC added to conditions array *
Process token 9 on line 3 [col:1;len:3;lvl:1;conds;T_START_HEREDOC;]: T_HEREDOC => foo\n
Process token 10 on line 4 [col:1;len:4;lvl:1;conds;T_START_HEREDOC;]: T_END_HEREDOC => HTML
=> Found scope closer for 8:T_START_HEREDOC
* token T_START_HEREDOC removed from conditions array *
* level decreased *
Process token 11 on line 4 [col:5;len:1;lvl:0;]: T_SEMICOLON => ;
Process token 12 on line 4 [col:6;len:0;lvl:0;]: T_WHITESPACE => \n
*** END LEVEL MAP ***
*** START ADDITIONAL PHP PROCESSING ***
icanhazstring, cb0 and jrfnl