squizlabs / PHP_CodeSniffer

PHP_CodeSniffer tokenizes PHP files and detects violations of a defined set of coding standards.
BSD 3-Clause "New" or "Revised" License
10.67k stars 1.48k forks source link

Tokenizer not applying tab replacement to heredoc/nowdoc closers #3639

Closed jrfnl closed 2 years ago

jrfnl commented 2 years ago

Since PHP 7.3, heredoc/nowdoc closers may be indented. This indent can use either tabs or spaces and the indent is included in the T_END_HEREDOC/T_END_NOWDOC token contents as received from the PHP native tokenizer.

However, the PHPCS Tokenizer did not execute tab replacement on these token leading to unexpected 'content' and incorrect 'length' values in the File::$tokens array, which in turn could lead to incorrect sniff results and incorrect fixes.

This commit adds the T_END_HEREDOC/T_END_NOWDOC tokens to the array of tokens for which to do tab replacement to make them more consistent with the rest of PHPCS.

I also considered splitting the token into a T_WHITESPACE token and the T_END_HEREDOC/T_END_NOWDOC token, but that could potentially break sniffs which expect the T_END_HEREDOC/T_END_NOWDOC token directly after the last T_HEREDOC/T_NOWDOC token. The current fix does not contain that risk.

Includes unit tests safeguarding this change.

The tests will only run on PHP 7.3+ as flexible heredoc/nowdocs don't tokenize correctly in PHP < 7.3.

gsherwood commented 2 years ago

Thank you for fixing this