This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace PhpSchool\PSXTest; |
||
4 | |||
5 | use PhpParser\Comment; |
||
6 | use PhpParser\Error; |
||
7 | use PhpParser\Parser\Tokens; |
||
8 | use PhpSchool\PSX\Lexer; |
||
9 | use PHPUnit_Framework_TestCase; |
||
10 | |||
11 | /** |
||
12 | * Class LexerTest |
||
13 | * @package PhpSchool\PSXTest |
||
14 | * @author Aydin Hassan <[email protected]> |
||
15 | */ |
||
16 | class LexerTest extends PHPUnit_Framework_TestCase |
||
17 | { |
||
18 | /* To allow overwriting in parent class */ |
||
19 | protected function getLexer(array $options = array()) |
||
20 | { |
||
21 | return new Lexer($options); |
||
22 | } |
||
23 | |||
24 | /** |
||
25 | * @dataProvider provideTestError |
||
26 | */ |
||
27 | public function testError($code, $message) |
||
28 | { |
||
29 | if (defined('HHVM_VERSION')) { |
||
30 | $this->markTestSkipped('HHVM does not throw warnings from token_get_all()'); |
||
31 | } |
||
32 | |||
33 | $lexer = $this->getLexer(); |
||
34 | try { |
||
35 | $lexer->startLexing($code); |
||
36 | } catch (Error $e) { |
||
37 | $this->assertSame($message, $e->getMessage()); |
||
38 | |||
39 | return; |
||
40 | } |
||
41 | |||
42 | $this->fail('Expected PhpParser\Error'); |
||
43 | } |
||
44 | |||
45 | public function provideTestError() |
||
46 | { |
||
47 | return array( |
||
48 | array('<?php /*', 'Unterminated comment on line 1'), |
||
49 | array('<?php ' . "\1", 'Unexpected character "' . "\1" . '" (ASCII 1) on unknown line'), |
||
50 | array('<?php ' . "\0", 'Unexpected null byte on unknown line'), |
||
51 | ); |
||
52 | } |
||
53 | |||
54 | /** |
||
55 | * @dataProvider provideTestLex |
||
56 | */ |
||
57 | public function testLex($code, $options, $tokens) |
||
58 | { |
||
59 | $lexer = $this->getLexer($options); |
||
60 | $lexer->startLexing($code); |
||
61 | while ($id = $lexer->getNextToken($value, $startAttributes, $endAttributes)) { |
||
62 | $token = array_shift($tokens); |
||
63 | |||
64 | $this->assertSame($token[0], $id); |
||
65 | $this->assertSame($token[1], $value); |
||
66 | $this->assertEquals($token[2], $startAttributes); |
||
67 | $this->assertEquals($token[3], $endAttributes); |
||
68 | } |
||
69 | } |
||
70 | |||
71 | public function provideTestLex() |
||
72 | { |
||
73 | return array( |
||
74 | // tests conversion of closing PHP tag and drop of whitespace and opening tags |
||
75 | array( |
||
76 | '<?php tokens ?>plaintext', |
||
77 | array(), |
||
78 | array( |
||
79 | array( |
||
80 | Tokens::T_STRING, 'tokens', |
||
81 | array('startLine' => 1), array('endLine' => 1) |
||
82 | ), |
||
83 | array( |
||
84 | ord(';'), '?>', |
||
85 | array('startLine' => 1), array('endLine' => 1) |
||
86 | ), |
||
87 | array( |
||
88 | Tokens::T_INLINE_HTML, 'plaintext', |
||
89 | array('startLine' => 1), array('endLine' => 1) |
||
90 | ), |
||
91 | ) |
||
92 | ), |
||
93 | // tests line numbers |
||
94 | array( |
||
95 | '<?php' . "\n" . '$ token /** doc' . "\n" . 'comment */ $', |
||
96 | array(), |
||
97 | array( |
||
98 | array( |
||
99 | ord('$'), '$', |
||
100 | array('startLine' => 2), array('endLine' => 2) |
||
101 | ), |
||
102 | array( |
||
103 | Tokens::T_STRING, 'token', |
||
104 | array('startLine' => 2), array('endLine' => 2) |
||
105 | ), |
||
106 | array( |
||
107 | ord('$'), '$', |
||
108 | array( |
||
109 | 'startLine' => 3, |
||
110 | 'comments' => array(new Comment\Doc('/** doc' . "\n" . 'comment */', 2)) |
||
111 | ), |
||
112 | array('endLine' => 3) |
||
113 | ), |
||
114 | ) |
||
115 | ), |
||
116 | // tests comment extraction |
||
117 | array( |
||
118 | '<?php /* comment */ // comment' . "\n" . '/** docComment 1 *//** docComment 2 */ token', |
||
119 | array(), |
||
120 | array( |
||
121 | array( |
||
122 | Tokens::T_STRING, 'token', |
||
123 | array( |
||
124 | 'startLine' => 2, |
||
125 | 'comments' => array( |
||
126 | new Comment('/* comment */', 1), |
||
127 | new Comment('// comment' . "\n", 1), |
||
128 | new Comment\Doc('/** docComment 1 */', 2), |
||
129 | new Comment\Doc('/** docComment 2 */', 2), |
||
130 | ), |
||
131 | ), |
||
132 | array('endLine' => 2) |
||
133 | ), |
||
134 | ) |
||
135 | ), |
||
136 | // tests differing start and end line |
||
137 | array( |
||
138 | '<?php "foo' . "\n" . 'bar"', |
||
139 | array(), |
||
140 | array( |
||
141 | array( |
||
142 | Tokens::T_CONSTANT_ENCAPSED_STRING, '"foo' . "\n" . 'bar"', |
||
143 | array('startLine' => 1), array('endLine' => 2, 'originalValue' => "\"foo\nbar\"") |
||
144 | ), |
||
145 | ) |
||
146 | ), |
||
147 | // tests exact file offsets |
||
148 | array( |
||
149 | '<?php "a";' . "\n" . '// foo' . "\n" . '"b";', |
||
150 | array('usedAttributes' => array('startFilePos', 'endFilePos')), |
||
151 | array( |
||
152 | array( |
||
153 | Tokens::T_CONSTANT_ENCAPSED_STRING, '"a"', |
||
154 | array('startFilePos' => 6), array('endFilePos' => 8, 'originalValue' => '"a"') |
||
155 | ), |
||
156 | array( |
||
157 | ord(';'), ';', |
||
158 | array('startFilePos' => 9), array('endFilePos' => 9) |
||
159 | ), |
||
160 | array( |
||
161 | Tokens::T_CONSTANT_ENCAPSED_STRING, '"b"', |
||
162 | array('startFilePos' => 18), array('endFilePos' => 20, 'originalValue' => '"b"') |
||
163 | ), |
||
164 | array( |
||
165 | ord(';'), ';', |
||
166 | array('startFilePos' => 21), array('endFilePos' => 21) |
||
167 | ), |
||
168 | ) |
||
169 | ), |
||
170 | // tests token offsets |
||
171 | array( |
||
172 | '<?php "a";' . "\n" . '// foo' . "\n" . '"b";', |
||
173 | array('usedAttributes' => array('startTokenPos', 'endTokenPos')), |
||
174 | array( |
||
175 | array( |
||
176 | Tokens::T_CONSTANT_ENCAPSED_STRING, '"a"', |
||
177 | array('startTokenPos' => 1), array('endTokenPos' => 1, 'originalValue' => '"a"') |
||
178 | ), |
||
179 | array( |
||
180 | ord(';'), ';', |
||
181 | array('startTokenPos' => 2), array('endTokenPos' => 2) |
||
182 | ), |
||
183 | array( |
||
184 | Tokens::T_CONSTANT_ENCAPSED_STRING, '"b"', |
||
185 | array('startTokenPos' => 5), array('endTokenPos' => 5, 'originalValue' => '"b"') |
||
186 | ), |
||
187 | array( |
||
188 | ord(';'), ';', |
||
189 | array('startTokenPos' => 6), array('endTokenPos' => 6) |
||
190 | ), |
||
191 | ) |
||
192 | ), |
||
193 | // tests all attributes being disabled |
||
194 | array( |
||
195 | '<?php /* foo */ $bar;', |
||
196 | array('usedAttributes' => array()), |
||
197 | array( |
||
198 | array( |
||
199 | Tokens::T_VARIABLE, '$bar', |
||
200 | array(), array() |
||
201 | ), |
||
202 | array( |
||
203 | ord(';'), ';', |
||
204 | array(), array() |
||
205 | ) |
||
206 | ) |
||
207 | ), |
||
208 | // test traditional array syntax |
||
209 | array( |
||
210 | '<?php $bar = array();', |
||
211 | array('usedAttributes' => array()), |
||
212 | array( |
||
213 | array( |
||
214 | Tokens::T_VARIABLE, '$bar', |
||
215 | array(), array() |
||
216 | ), |
||
217 | array( |
||
218 | ord('='), '=', |
||
219 | array(), array() |
||
220 | ), |
||
221 | array( |
||
222 | Tokens::T_ARRAY, 'array', |
||
223 | array('traditionalArray' => true), array() |
||
224 | ), |
||
225 | array( |
||
226 | ord('('), '(', |
||
227 | array(), array() |
||
228 | ), |
||
229 | array( |
||
230 | ord(')'), ')', |
||
231 | array(), array() |
||
232 | ), |
||
233 | array( |
||
234 | ord(';'), ';', |
||
235 | array(), array() |
||
236 | ) |
||
237 | ) |
||
238 | ), |
||
239 | array( |
||
240 | '<?php die;', |
||
241 | array('usedAttributes' => array()), |
||
242 | array( |
||
243 | array( |
||
244 | Tokens::T_EXIT, 'die', |
||
245 | array('isDie' => true), array() |
||
246 | ), |
||
247 | array( |
||
248 | ord(';'), ';', |
||
249 | array(), array() |
||
250 | ) |
||
251 | ) |
||
252 | ) |
||
253 | ); |
||
254 | } |
||
255 | |||
256 | /** |
||
257 | * @dataProvider provideTestHaltCompiler |
||
258 | */ |
||
259 | public function testHandleHaltCompiler($code, $remaining) |
||
260 | { |
||
261 | $lexer = $this->getLexer(); |
||
262 | $lexer->startLexing($code); |
||
263 | |||
264 | while (Tokens::T_HALT_COMPILER !== $lexer->getNextToken()) { |
||
265 | } |
||
266 | |||
267 | $this->assertSame($remaining, $lexer->handleHaltCompiler()); |
||
268 | $this->assertSame(0, $lexer->getNextToken()); |
||
269 | } |
||
270 | |||
271 | public function provideTestHaltCompiler() |
||
272 | { |
||
273 | return array( |
||
274 | array('<?php ... __halt_compiler();Remaining Text', 'Remaining Text'), |
||
275 | array('<?php ... __halt_compiler ( ) ;Remaining Text', 'Remaining Text'), |
||
276 | array('<?php ... __halt_compiler() ?>Remaining Text', 'Remaining Text'), |
||
277 | //array('<?php ... __halt_compiler();' . "\0", "\0"), |
||
0 ignored issues
–
show
|
|||
278 | //array('<?php ... __halt_compiler /* */ ( ) ;Remaining Text', 'Remaining Text'), |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
88% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
279 | ); |
||
280 | } |
||
281 | |||
282 | /** |
||
283 | * @expectedException \PhpParser\Error |
||
284 | * @expectedExceptionMessage __HALT_COMPILER must be followed by "();" |
||
285 | */ |
||
286 | public function testHandleHaltCompilerError() |
||
287 | { |
||
288 | $lexer = $this->getLexer(); |
||
289 | $lexer->startLexing('<?php ... __halt_compiler invalid ();'); |
||
290 | |||
291 | while (Tokens::T_HALT_COMPILER !== $lexer->getNextToken()) { |
||
292 | } |
||
293 | $lexer->handleHaltCompiler(); |
||
294 | } |
||
295 | |||
296 | public function testGetTokens() |
||
297 | { |
||
298 | $code = '<?php "a";' . "\n" . '// foo' . "\n" . '"b";'; |
||
299 | $expectedTokens = array( |
||
300 | array(T_OPEN_TAG, '<?php ', 1), |
||
301 | array(T_CONSTANT_ENCAPSED_STRING, '"a"', 1), |
||
302 | ';', |
||
303 | array(T_WHITESPACE, "\n", 1), |
||
304 | array(T_COMMENT, '// foo' . "\n", 2), |
||
305 | array(T_CONSTANT_ENCAPSED_STRING, '"b"', 3), |
||
306 | ';', |
||
307 | ); |
||
308 | |||
309 | $lexer = $this->getLexer(); |
||
310 | $lexer->startLexing($code); |
||
311 | $this->assertSame($expectedTokens, $lexer->getTokens()); |
||
312 | } |
||
313 | } |
||
314 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.