annotate vendor/nikic/php-parser/test/PhpParser/LexerTest.php @ 13:5fb285c0d0e3

Update Drupal core to 8.4.7 via Composer. Security update; I *think* we've been lucky to get away with this so far, as we don't support self-registration which seems to be used by the so-called "drupalgeddon 2" attack that 8.4.5 was vulnerable to.
author Chris Cannam
date Mon, 23 Apr 2018 09:33:26 +0100
parents 4c8ae668cc8c
children 129ea1e6d783
rev   line source
Chris@13 1 <?php declare(strict_types=1);
Chris@0 2
Chris@0 3 namespace PhpParser;
Chris@0 4
Chris@0 5 use PhpParser\Parser\Tokens;
Chris@13 6 use PHPUnit\Framework\TestCase;
Chris@0 7
Chris@13 8 class LexerTest extends TestCase
Chris@0 9 {
Chris@0 10 /* To allow overwriting in parent class */
Chris@13 11 protected function getLexer(array $options = []) {
Chris@0 12 return new Lexer($options);
Chris@0 13 }
Chris@0 14
Chris@0 15 /**
Chris@0 16 * @dataProvider provideTestError
Chris@0 17 */
Chris@0 18 public function testError($code, $messages) {
Chris@0 19 if (defined('HHVM_VERSION')) {
Chris@0 20 $this->markTestSkipped('HHVM does not throw warnings from token_get_all()');
Chris@0 21 }
Chris@0 22
Chris@0 23 $errorHandler = new ErrorHandler\Collecting();
Chris@0 24 $lexer = $this->getLexer(['usedAttributes' => [
Chris@0 25 'comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos'
Chris@0 26 ]]);
Chris@0 27 $lexer->startLexing($code, $errorHandler);
Chris@0 28 $errors = $errorHandler->getErrors();
Chris@0 29
Chris@13 30 $this->assertCount(count($messages), $errors);
Chris@0 31 for ($i = 0; $i < count($messages); $i++) {
Chris@0 32 $this->assertSame($messages[$i], $errors[$i]->getMessageWithColumnInfo($code));
Chris@0 33 }
Chris@0 34 }
Chris@0 35
Chris@0 36 public function provideTestError() {
Chris@13 37 return [
Chris@13 38 ["<?php /*", ["Unterminated comment from 1:7 to 1:9"]],
Chris@13 39 ["<?php \1", ["Unexpected character \"\1\" (ASCII 1) from 1:7 to 1:7"]],
Chris@13 40 ["<?php \0", ["Unexpected null byte from 1:7 to 1:7"]],
Chris@0 41 // Error with potentially emulated token
Chris@13 42 ["<?php ?? \0", ["Unexpected null byte from 1:10 to 1:10"]],
Chris@13 43 ["<?php\n\0\1 foo /* bar", [
Chris@0 44 "Unexpected null byte from 2:1 to 2:1",
Chris@0 45 "Unexpected character \"\1\" (ASCII 1) from 2:2 to 2:2",
Chris@0 46 "Unterminated comment from 2:8 to 2:14"
Chris@13 47 ]],
Chris@13 48 ];
Chris@0 49 }
Chris@0 50
Chris@0 51 /**
Chris@0 52 * @dataProvider provideTestLex
Chris@0 53 */
Chris@0 54 public function testLex($code, $options, $tokens) {
Chris@0 55 $lexer = $this->getLexer($options);
Chris@0 56 $lexer->startLexing($code);
Chris@0 57 while ($id = $lexer->getNextToken($value, $startAttributes, $endAttributes)) {
Chris@0 58 $token = array_shift($tokens);
Chris@0 59
Chris@0 60 $this->assertSame($token[0], $id);
Chris@0 61 $this->assertSame($token[1], $value);
Chris@0 62 $this->assertEquals($token[2], $startAttributes);
Chris@0 63 $this->assertEquals($token[3], $endAttributes);
Chris@0 64 }
Chris@0 65 }
Chris@0 66
Chris@0 67 public function provideTestLex() {
Chris@13 68 return [
Chris@0 69 // tests conversion of closing PHP tag and drop of whitespace and opening tags
Chris@13 70 [
Chris@0 71 '<?php tokens ?>plaintext',
Chris@13 72 [],
Chris@13 73 [
Chris@13 74 [
Chris@0 75 Tokens::T_STRING, 'tokens',
Chris@13 76 ['startLine' => 1], ['endLine' => 1]
Chris@13 77 ],
Chris@13 78 [
Chris@0 79 ord(';'), '?>',
Chris@13 80 ['startLine' => 1], ['endLine' => 1]
Chris@13 81 ],
Chris@13 82 [
Chris@0 83 Tokens::T_INLINE_HTML, 'plaintext',
Chris@13 84 ['startLine' => 1, 'hasLeadingNewline' => false],
Chris@13 85 ['endLine' => 1]
Chris@13 86 ],
Chris@13 87 ]
Chris@13 88 ],
Chris@0 89 // tests line numbers
Chris@13 90 [
Chris@0 91 '<?php' . "\n" . '$ token /** doc' . "\n" . 'comment */ $',
Chris@13 92 [],
Chris@13 93 [
Chris@13 94 [
Chris@0 95 ord('$'), '$',
Chris@13 96 ['startLine' => 2], ['endLine' => 2]
Chris@13 97 ],
Chris@13 98 [
Chris@0 99 Tokens::T_STRING, 'token',
Chris@13 100 ['startLine' => 2], ['endLine' => 2]
Chris@13 101 ],
Chris@13 102 [
Chris@0 103 ord('$'), '$',
Chris@13 104 [
Chris@0 105 'startLine' => 3,
Chris@13 106 'comments' => [
Chris@13 107 new Comment\Doc('/** doc' . "\n" . 'comment */', 2, 14, 5),
Chris@13 108 ]
Chris@13 109 ],
Chris@13 110 ['endLine' => 3]
Chris@13 111 ],
Chris@13 112 ]
Chris@13 113 ],
Chris@0 114 // tests comment extraction
Chris@13 115 [
Chris@0 116 '<?php /* comment */ // comment' . "\n" . '/** docComment 1 *//** docComment 2 */ token',
Chris@13 117 [],
Chris@13 118 [
Chris@13 119 [
Chris@0 120 Tokens::T_STRING, 'token',
Chris@13 121 [
Chris@0 122 'startLine' => 2,
Chris@13 123 'comments' => [
Chris@13 124 new Comment('/* comment */', 1, 6, 1),
Chris@13 125 new Comment('// comment' . "\n", 1, 20, 3),
Chris@13 126 new Comment\Doc('/** docComment 1 */', 2, 31, 4),
Chris@13 127 new Comment\Doc('/** docComment 2 */', 2, 50, 5),
Chris@13 128 ],
Chris@13 129 ],
Chris@13 130 ['endLine' => 2]
Chris@13 131 ],
Chris@13 132 ]
Chris@13 133 ],
Chris@0 134 // tests differing start and end line
Chris@13 135 [
Chris@0 136 '<?php "foo' . "\n" . 'bar"',
Chris@13 137 [],
Chris@13 138 [
Chris@13 139 [
Chris@0 140 Tokens::T_CONSTANT_ENCAPSED_STRING, '"foo' . "\n" . 'bar"',
Chris@13 141 ['startLine' => 1], ['endLine' => 2]
Chris@13 142 ],
Chris@13 143 ]
Chris@13 144 ],
Chris@0 145 // tests exact file offsets
Chris@13 146 [
Chris@0 147 '<?php "a";' . "\n" . '// foo' . "\n" . '"b";',
Chris@13 148 ['usedAttributes' => ['startFilePos', 'endFilePos']],
Chris@13 149 [
Chris@13 150 [
Chris@0 151 Tokens::T_CONSTANT_ENCAPSED_STRING, '"a"',
Chris@13 152 ['startFilePos' => 6], ['endFilePos' => 8]
Chris@13 153 ],
Chris@13 154 [
Chris@0 155 ord(';'), ';',
Chris@13 156 ['startFilePos' => 9], ['endFilePos' => 9]
Chris@13 157 ],
Chris@13 158 [
Chris@0 159 Tokens::T_CONSTANT_ENCAPSED_STRING, '"b"',
Chris@13 160 ['startFilePos' => 18], ['endFilePos' => 20]
Chris@13 161 ],
Chris@13 162 [
Chris@0 163 ord(';'), ';',
Chris@13 164 ['startFilePos' => 21], ['endFilePos' => 21]
Chris@13 165 ],
Chris@13 166 ]
Chris@13 167 ],
Chris@0 168 // tests token offsets
Chris@13 169 [
Chris@0 170 '<?php "a";' . "\n" . '// foo' . "\n" . '"b";',
Chris@13 171 ['usedAttributes' => ['startTokenPos', 'endTokenPos']],
Chris@13 172 [
Chris@13 173 [
Chris@0 174 Tokens::T_CONSTANT_ENCAPSED_STRING, '"a"',
Chris@13 175 ['startTokenPos' => 1], ['endTokenPos' => 1]
Chris@13 176 ],
Chris@13 177 [
Chris@0 178 ord(';'), ';',
Chris@13 179 ['startTokenPos' => 2], ['endTokenPos' => 2]
Chris@13 180 ],
Chris@13 181 [
Chris@0 182 Tokens::T_CONSTANT_ENCAPSED_STRING, '"b"',
Chris@13 183 ['startTokenPos' => 5], ['endTokenPos' => 5]
Chris@13 184 ],
Chris@13 185 [
Chris@0 186 ord(';'), ';',
Chris@13 187 ['startTokenPos' => 6], ['endTokenPos' => 6]
Chris@13 188 ],
Chris@13 189 ]
Chris@13 190 ],
Chris@0 191 // tests all attributes being disabled
Chris@13 192 [
Chris@0 193 '<?php /* foo */ $bar;',
Chris@13 194 ['usedAttributes' => []],
Chris@13 195 [
Chris@13 196 [
Chris@0 197 Tokens::T_VARIABLE, '$bar',
Chris@13 198 [], []
Chris@13 199 ],
Chris@13 200 [
Chris@0 201 ord(';'), ';',
Chris@13 202 [], []
Chris@13 203 ]
Chris@13 204 ]
Chris@13 205 ],
Chris@0 206 // tests no tokens
Chris@13 207 [
Chris@0 208 '',
Chris@13 209 [],
Chris@13 210 []
Chris@13 211 ],
Chris@13 212 ];
Chris@0 213 }
Chris@0 214
Chris@0 215 /**
Chris@0 216 * @dataProvider provideTestHaltCompiler
Chris@0 217 */
Chris@0 218 public function testHandleHaltCompiler($code, $remaining) {
Chris@0 219 $lexer = $this->getLexer();
Chris@0 220 $lexer->startLexing($code);
Chris@0 221
Chris@0 222 while (Tokens::T_HALT_COMPILER !== $lexer->getNextToken());
Chris@0 223
Chris@0 224 $this->assertSame($remaining, $lexer->handleHaltCompiler());
Chris@0 225 $this->assertSame(0, $lexer->getNextToken());
Chris@0 226 }
Chris@0 227
Chris@0 228 public function provideTestHaltCompiler() {
Chris@13 229 return [
Chris@13 230 ['<?php ... __halt_compiler();Remaining Text', 'Remaining Text'],
Chris@13 231 ['<?php ... __halt_compiler ( ) ;Remaining Text', 'Remaining Text'],
Chris@13 232 ['<?php ... __halt_compiler() ?>Remaining Text', 'Remaining Text'],
Chris@0 233 //array('<?php ... __halt_compiler();' . "\0", "\0"),
Chris@0 234 //array('<?php ... __halt_compiler /* */ ( ) ;Remaining Text', 'Remaining Text'),
Chris@13 235 ];
Chris@0 236 }
Chris@0 237
Chris@0 238 /**
Chris@0 239 * @expectedException \PhpParser\Error
Chris@0 240 * @expectedExceptionMessage __HALT_COMPILER must be followed by "();"
Chris@0 241 */
Chris@0 242 public function testHandleHaltCompilerError() {
Chris@0 243 $lexer = $this->getLexer();
Chris@0 244 $lexer->startLexing('<?php ... __halt_compiler invalid ();');
Chris@0 245
Chris@0 246 while (Tokens::T_HALT_COMPILER !== $lexer->getNextToken());
Chris@0 247 $lexer->handleHaltCompiler();
Chris@0 248 }
Chris@0 249
Chris@0 250 public function testGetTokens() {
Chris@0 251 $code = '<?php "a";' . "\n" . '// foo' . "\n" . '"b";';
Chris@13 252 $expectedTokens = [
Chris@13 253 [T_OPEN_TAG, '<?php ', 1],
Chris@13 254 [T_CONSTANT_ENCAPSED_STRING, '"a"', 1],
Chris@0 255 ';',
Chris@13 256 [T_WHITESPACE, "\n", 1],
Chris@13 257 [T_COMMENT, '// foo' . "\n", 2],
Chris@13 258 [T_CONSTANT_ENCAPSED_STRING, '"b"', 3],
Chris@0 259 ';',
Chris@13 260 ];
Chris@0 261
Chris@0 262 $lexer = $this->getLexer();
Chris@0 263 $lexer->startLexing($code);
Chris@0 264 $this->assertSame($expectedTokens, $lexer->getTokens());
Chris@0 265 }
Chris@0 266 }