Skip to content

Commit fe4dde5

Browse files
committed
Merge branch 'feature/tokenizer-php-bugfix-double-quoted-strings' of https://github.com/jrfnl/PHP_CodeSniffer
2 parents 7f5c55d + 150c8c4 commit fe4dde5

File tree

4 files changed

+196
-1
lines changed

4 files changed

+196
-1
lines changed

package.xml

+6
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
184184
<file baseinstalldir="" name="DefaultKeywordTest.php" role="test" />
185185
<file baseinstalldir="" name="DoubleArrowTest.inc" role="test" />
186186
<file baseinstalldir="" name="DoubleArrowTest.php" role="test" />
187+
<file baseinstalldir="" name="DoubleQuotedStringTest.inc" role="test" />
188+
<file baseinstalldir="" name="DoubleQuotedStringTest.php" role="test" />
187189
<file baseinstalldir="" name="EnumCaseTest.inc" role="test" />
188190
<file baseinstalldir="" name="EnumCaseTest.php" role="test" />
189191
<file baseinstalldir="" name="FinallyTest.inc" role="test" />
@@ -2155,6 +2157,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
21552157
<install as="CodeSniffer/Core/Tokenizer/DefaultKeywordTest.inc" name="tests/Core/Tokenizer/DefaultKeywordTest.inc" />
21562158
<install as="CodeSniffer/Core/Tokenizer/DoubleArrowTest.php" name="tests/Core/Tokenizer/DoubleArrowTest.php" />
21572159
<install as="CodeSniffer/Core/Tokenizer/DoubleArrowTest.inc" name="tests/Core/Tokenizer/DoubleArrowTest.inc" />
2160+
<install as="CodeSniffer/Core/Tokenizer/DoubleQuotedStringTest.php" name="tests/Core/Tokenizer/DoubleQuotedStringTest.php" />
2161+
<install as="CodeSniffer/Core/Tokenizer/DoubleQuotedStringTest.inc" name="tests/Core/Tokenizer/DoubleQuotedStringTest.inc" />
21582162
<install as="CodeSniffer/Core/Tokenizer/EnumCaseTest.php" name="tests/Core/Tokenizer/EnumCaseTest.php" />
21592163
<install as="CodeSniffer/Core/Tokenizer/EnumCaseTest.inc" name="tests/Core/Tokenizer/EnumCaseTest.inc" />
21602164
<install as="CodeSniffer/Core/Tokenizer/FinallyTest.php" name="tests/Core/Tokenizer/FinallyTest.php" />
@@ -2257,6 +2261,8 @@ http://pear.php.net/dtd/package-2.0.xsd">
22572261
<install as="CodeSniffer/Core/Tokenizer/DefaultKeywordTest.inc" name="tests/Core/Tokenizer/DefaultKeywordTest.inc" />
22582262
<install as="CodeSniffer/Core/Tokenizer/DoubleArrowTest.php" name="tests/Core/Tokenizer/DoubleArrowTest.php" />
22592263
<install as="CodeSniffer/Core/Tokenizer/DoubleArrowTest.inc" name="tests/Core/Tokenizer/DoubleArrowTest.inc" />
2264+
<install as="CodeSniffer/Core/Tokenizer/DoubleQuotedStringTest.php" name="tests/Core/Tokenizer/DoubleQuotedStringTest.php" />
2265+
<install as="CodeSniffer/Core/Tokenizer/DoubleQuotedStringTest.inc" name="tests/Core/Tokenizer/DoubleQuotedStringTest.inc" />
22602266
<install as="CodeSniffer/Core/Tokenizer/EnumCaseTest.php" name="tests/Core/Tokenizer/EnumCaseTest.php" />
22612267
<install as="CodeSniffer/Core/Tokenizer/EnumCaseTest.inc" name="tests/Core/Tokenizer/EnumCaseTest.inc" />
22622268
<install as="CodeSniffer/Core/Tokenizer/FinallyTest.php" name="tests/Core/Tokenizer/FinallyTest.php" />

src/Tokenizers/PHP.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,8 @@ protected function tokenize($string)
824824

825825
if ($subTokenIsArray === true) {
826826
$tokenContent .= $subToken[1];
827-
if ($subToken[1] === '{'
827+
if (($subToken[1] === '{'
828+
|| $subToken[1] === '${')
828829
&& $subToken[0] !== T_ENCAPSED_AND_WHITESPACE
829830
) {
830831
$nestedVars[] = $i;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
// Test source: https://gist.github.com/iluuu1994/72e2154fc4150f2258316b0255b698f2#file-test-php
4+
5+
/* testSimple1 */
6+
"$foo";
7+
/* testSimple2 */
8+
"{$foo}";
9+
/* testSimple3 */
10+
"${foo}";
11+
12+
/* testDIM1 */
13+
"$foo[bar]";
14+
/* testDIM2 */
15+
"{$foo['bar']}";
16+
/* testDIM3 */
17+
"${foo['bar']}";
18+
19+
/* testProperty1 */
20+
"$foo->bar";
21+
/* testProperty2 */
22+
"{$foo->bar}";
23+
24+
/* testMethod1 */
25+
"{$foo->bar()}";
26+
27+
/* testClosure1 */
28+
"{$foo()}";
29+
30+
/* testChain1 */
31+
"{$foo['bar']->baz()()}";
32+
33+
/* testVariableVar1 */
34+
"${$bar}";
35+
/* testVariableVar2 */
36+
"${(foo)}";
37+
/* testVariableVar3 */
38+
"${foo->bar}";
39+
40+
/* testNested1 */
41+
"${foo["${bar}"]}";
42+
/* testNested2 */
43+
"${foo["${bar['baz']}"]}";
44+
/* testNested3 */
45+
"${foo->{$baz}}";
46+
/* testNested4 */
47+
"${foo->{${'a'}}}";
48+
/* testNested5 */
49+
"${foo->{"${'a'}"}}";
50+
51+
/* testParseError */
52+
"${foo["${bar
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?php
2+
/**
3+
* Tests that embedded variables and expressions in double quoted strings are tokenized
4+
* as one double quoted string token.
5+
*
6+
* @author Juliette Reinders Folmer <[email protected]>
7+
* @copyright 2022 Squiz Pty Ltd (ABN 77 084 670 600)
8+
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
9+
*/
10+
11+
namespace PHP_CodeSniffer\Tests\Core\Tokenizer;
12+
13+
use PHP_CodeSniffer\Tests\Core\AbstractMethodUnitTest;
14+
15+
class DoubleQuotedStringTest extends AbstractMethodUnitTest
16+
{
17+
18+
19+
/**
20+
* Test that double quoted strings contain the complete string.
21+
*
22+
* @param string $testMarker The comment which prefaces the target token in the test file.
23+
* @param string $expectedContent The expected content of the double quoted string.
24+
*
25+
* @dataProvider dataDoubleQuotedString
26+
* @covers PHP_CodeSniffer\Tokenizers\PHP::tokenize
27+
*
28+
* @return void
29+
*/
30+
public function testDoubleQuotedString($testMarker, $expectedContent)
31+
{
32+
$tokens = self::$phpcsFile->getTokens();
33+
34+
$target = $this->getTargetToken($testMarker, T_DOUBLE_QUOTED_STRING);
35+
$this->assertSame($expectedContent, $tokens[$target]['content']);
36+
37+
}//end testDoubleQuotedString()
38+
39+
40+
/**
41+
* Data provider.
42+
*
43+
* @see testDoubleQuotedString()
44+
*
45+
* @return array
46+
*/
47+
public function dataDoubleQuotedString()
48+
{
49+
return [
50+
[
51+
'testMarker' => '/* testSimple1 */',
52+
'expectedContent' => '"$foo"',
53+
],
54+
[
55+
'testMarker' => '/* testSimple2 */',
56+
'expectedContent' => '"{$foo}"',
57+
],
58+
[
59+
'testMarker' => '/* testSimple3 */',
60+
'expectedContent' => '"${foo}"',
61+
],
62+
[
63+
'testMarker' => '/* testDIM1 */',
64+
'expectedContent' => '"$foo[bar]"',
65+
],
66+
[
67+
'testMarker' => '/* testDIM2 */',
68+
'expectedContent' => '"{$foo[\'bar\']}"',
69+
],
70+
[
71+
'testMarker' => '/* testDIM3 */',
72+
'expectedContent' => '"${foo[\'bar\']}"',
73+
],
74+
[
75+
'testMarker' => '/* testProperty1 */',
76+
'expectedContent' => '"$foo->bar"',
77+
],
78+
[
79+
'testMarker' => '/* testProperty2 */',
80+
'expectedContent' => '"{$foo->bar}"',
81+
],
82+
[
83+
'testMarker' => '/* testMethod1 */',
84+
'expectedContent' => '"{$foo->bar()}"',
85+
],
86+
[
87+
'testMarker' => '/* testClosure1 */',
88+
'expectedContent' => '"{$foo()}"',
89+
],
90+
[
91+
'testMarker' => '/* testChain1 */',
92+
'expectedContent' => '"{$foo[\'bar\']->baz()()}"',
93+
],
94+
[
95+
'testMarker' => '/* testVariableVar1 */',
96+
'expectedContent' => '"${$bar}"',
97+
],
98+
[
99+
'testMarker' => '/* testVariableVar2 */',
100+
'expectedContent' => '"${(foo)}"',
101+
],
102+
[
103+
'testMarker' => '/* testVariableVar3 */',
104+
'expectedContent' => '"${foo->bar}"',
105+
],
106+
[
107+
'testMarker' => '/* testNested1 */',
108+
'expectedContent' => '"${foo["${bar}"]}"',
109+
],
110+
[
111+
'testMarker' => '/* testNested2 */',
112+
'expectedContent' => '"${foo["${bar[\'baz\']}"]}"',
113+
],
114+
[
115+
'testMarker' => '/* testNested3 */',
116+
'expectedContent' => '"${foo->{$baz}}"',
117+
],
118+
[
119+
'testMarker' => '/* testNested4 */',
120+
'expectedContent' => '"${foo->{${\'a\'}}}"',
121+
],
122+
[
123+
'testMarker' => '/* testNested5 */',
124+
'expectedContent' => '"${foo->{"${\'a\'}"}}"',
125+
],
126+
[
127+
'testMarker' => '/* testParseError */',
128+
'expectedContent' => '"${foo["${bar
129+
',
130+
],
131+
];
132+
133+
}//end dataDoubleQuotedString()
134+
135+
136+
}//end class

0 commit comments

Comments
 (0)