Skip to content

Commit

Permalink
Merge branch 'feature/tokenizer-php-bugfix-double-quoted-strings' of h…
Browse files Browse the repository at this point in the history
  • Loading branch information
gsherwood committed Jun 13, 2022
2 parents 7f5c55d + 150c8c4 commit fe4dde5
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 1 deletion.
6 changes: 6 additions & 0 deletions package.xml
Expand Up @@ -184,6 +184,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
<file baseinstalldir="" name="DefaultKeywordTest.php" role="test" />
<file baseinstalldir="" name="DoubleArrowTest.inc" role="test" />
<file baseinstalldir="" name="DoubleArrowTest.php" role="test" />
<file baseinstalldir="" name="DoubleQuotedStringTest.inc" role="test" />
<file baseinstalldir="" name="DoubleQuotedStringTest.php" role="test" />
<file baseinstalldir="" name="EnumCaseTest.inc" role="test" />
<file baseinstalldir="" name="EnumCaseTest.php" role="test" />
<file baseinstalldir="" name="FinallyTest.inc" role="test" />
Expand Down Expand Up @@ -2155,6 +2157,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
<install as="CodeSniffer/Core/Tokenizer/DefaultKeywordTest.inc" name="tests/Core/Tokenizer/DefaultKeywordTest.inc" />
<install as="CodeSniffer/Core/Tokenizer/DoubleArrowTest.php" name="tests/Core/Tokenizer/DoubleArrowTest.php" />
<install as="CodeSniffer/Core/Tokenizer/DoubleArrowTest.inc" name="tests/Core/Tokenizer/DoubleArrowTest.inc" />
<install as="CodeSniffer/Core/Tokenizer/DoubleQuotedStringTest.php" name="tests/Core/Tokenizer/DoubleQuotedStringTest.php" />
<install as="CodeSniffer/Core/Tokenizer/DoubleQuotedStringTest.inc" name="tests/Core/Tokenizer/DoubleQuotedStringTest.inc" />
<install as="CodeSniffer/Core/Tokenizer/EnumCaseTest.php" name="tests/Core/Tokenizer/EnumCaseTest.php" />
<install as="CodeSniffer/Core/Tokenizer/EnumCaseTest.inc" name="tests/Core/Tokenizer/EnumCaseTest.inc" />
<install as="CodeSniffer/Core/Tokenizer/FinallyTest.php" name="tests/Core/Tokenizer/FinallyTest.php" />
Expand Down Expand Up @@ -2257,6 +2261,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
<install as="CodeSniffer/Core/Tokenizer/DefaultKeywordTest.inc" name="tests/Core/Tokenizer/DefaultKeywordTest.inc" />
<install as="CodeSniffer/Core/Tokenizer/DoubleArrowTest.php" name="tests/Core/Tokenizer/DoubleArrowTest.php" />
<install as="CodeSniffer/Core/Tokenizer/DoubleArrowTest.inc" name="tests/Core/Tokenizer/DoubleArrowTest.inc" />
<install as="CodeSniffer/Core/Tokenizer/DoubleQuotedStringTest.php" name="tests/Core/Tokenizer/DoubleQuotedStringTest.php" />
<install as="CodeSniffer/Core/Tokenizer/DoubleQuotedStringTest.inc" name="tests/Core/Tokenizer/DoubleQuotedStringTest.inc" />
<install as="CodeSniffer/Core/Tokenizer/EnumCaseTest.php" name="tests/Core/Tokenizer/EnumCaseTest.php" />
<install as="CodeSniffer/Core/Tokenizer/EnumCaseTest.inc" name="tests/Core/Tokenizer/EnumCaseTest.inc" />
<install as="CodeSniffer/Core/Tokenizer/FinallyTest.php" name="tests/Core/Tokenizer/FinallyTest.php" />
Expand Down
3 changes: 2 additions & 1 deletion src/Tokenizers/PHP.php
Expand Up @@ -824,7 +824,8 @@ protected function tokenize($string)

if ($subTokenIsArray === true) {
$tokenContent .= $subToken[1];
if ($subToken[1] === '{'
if (($subToken[1] === '{'
|| $subToken[1] === '${')
&& $subToken[0] !== T_ENCAPSED_AND_WHITESPACE
) {
$nestedVars[] = $i;
Expand Down
52 changes: 52 additions & 0 deletions tests/Core/Tokenizer/DoubleQuotedStringTest.inc
@@ -0,0 +1,52 @@
<?php

// Test source: https://gist.github.com/iluuu1994/72e2154fc4150f2258316b0255b698f2#file-test-php

/* testSimple1 */
"$foo";
/* testSimple2 */
"{$foo}";
/* testSimple3 */
"${foo}";

/* testDIM1 */
"$foo[bar]";
/* testDIM2 */
"{$foo['bar']}";
/* testDIM3 */
"${foo['bar']}";

/* testProperty1 */
"$foo->bar";
/* testProperty2 */
"{$foo->bar}";

/* testMethod1 */
"{$foo->bar()}";

/* testClosure1 */
"{$foo()}";

/* testChain1 */
"{$foo['bar']->baz()()}";

/* testVariableVar1 */
"${$bar}";
/* testVariableVar2 */
"${(foo)}";
/* testVariableVar3 */
"${foo->bar}";

/* testNested1 */
"${foo["${bar}"]}";
/* testNested2 */
"${foo["${bar['baz']}"]}";
/* testNested3 */
"${foo->{$baz}}";
/* testNested4 */
"${foo->{${'a'}}}";
/* testNested5 */
"${foo->{"${'a'}"}}";

/* testParseError */
"${foo["${bar
136 changes: 136 additions & 0 deletions tests/Core/Tokenizer/DoubleQuotedStringTest.php
@@ -0,0 +1,136 @@
<?php
/**
* Tests that embedded variables and expressions in double quoted strings are tokenized
* as one double quoted string token.
*
* @author Juliette Reinders Folmer <phpcs_nospam@adviesenzo.nl>
* @copyright 2022 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/

namespace PHP_CodeSniffer\Tests\Core\Tokenizer;

use PHP_CodeSniffer\Tests\Core\AbstractMethodUnitTest;

class DoubleQuotedStringTest extends AbstractMethodUnitTest
{


/**
* Test that double quoted strings contain the complete string.
*
* @param string $testMarker The comment which prefaces the target token in the test file.
* @param string $expectedContent The expected content of the double quoted string.
*
* @dataProvider dataDoubleQuotedString
* @covers PHP_CodeSniffer\Tokenizers\PHP::tokenize
*
* @return void
*/
public function testDoubleQuotedString($testMarker, $expectedContent)
{
$tokens = self::$phpcsFile->getTokens();

$target = $this->getTargetToken($testMarker, T_DOUBLE_QUOTED_STRING);
$this->assertSame($expectedContent, $tokens[$target]['content']);

}//end testDoubleQuotedString()


/**
* Data provider.
*
* @see testDoubleQuotedString()
*
* @return array
*/
public function dataDoubleQuotedString()
{
return [
[
'testMarker' => '/* testSimple1 */',
'expectedContent' => '"$foo"',
],
[
'testMarker' => '/* testSimple2 */',
'expectedContent' => '"{$foo}"',
],
[
'testMarker' => '/* testSimple3 */',
'expectedContent' => '"${foo}"',
],
[
'testMarker' => '/* testDIM1 */',
'expectedContent' => '"$foo[bar]"',
],
[
'testMarker' => '/* testDIM2 */',
'expectedContent' => '"{$foo[\'bar\']}"',
],
[
'testMarker' => '/* testDIM3 */',
'expectedContent' => '"${foo[\'bar\']}"',
],
[
'testMarker' => '/* testProperty1 */',
'expectedContent' => '"$foo->bar"',
],
[
'testMarker' => '/* testProperty2 */',
'expectedContent' => '"{$foo->bar}"',
],
[
'testMarker' => '/* testMethod1 */',
'expectedContent' => '"{$foo->bar()}"',
],
[
'testMarker' => '/* testClosure1 */',
'expectedContent' => '"{$foo()}"',
],
[
'testMarker' => '/* testChain1 */',
'expectedContent' => '"{$foo[\'bar\']->baz()()}"',
],
[
'testMarker' => '/* testVariableVar1 */',
'expectedContent' => '"${$bar}"',
],
[
'testMarker' => '/* testVariableVar2 */',
'expectedContent' => '"${(foo)}"',
],
[
'testMarker' => '/* testVariableVar3 */',
'expectedContent' => '"${foo->bar}"',
],
[
'testMarker' => '/* testNested1 */',
'expectedContent' => '"${foo["${bar}"]}"',
],
[
'testMarker' => '/* testNested2 */',
'expectedContent' => '"${foo["${bar[\'baz\']}"]}"',
],
[
'testMarker' => '/* testNested3 */',
'expectedContent' => '"${foo->{$baz}}"',
],
[
'testMarker' => '/* testNested4 */',
'expectedContent' => '"${foo->{${\'a\'}}}"',
],
[
'testMarker' => '/* testNested5 */',
'expectedContent' => '"${foo->{"${\'a\'}"}}"',
],
[
'testMarker' => '/* testParseError */',
'expectedContent' => '"${foo["${bar
',
],
];

}//end dataDoubleQuotedString()


}//end class

0 comments on commit fe4dde5

Please sign in to comment.