annotate vendor/nikic/php-parser/test/PhpParser/ParserTest.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\Node\Expr;
Chris@0 6 use PhpParser\Node\Scalar;
Chris@0 7 use PhpParser\Node\Scalar\String_;
Chris@13 8 use PhpParser\Node\Stmt;
Chris@13 9 use PHPUnit\Framework\TestCase;
Chris@0 10
Chris@13 11 abstract class ParserTest extends TestCase
Chris@0 12 {
Chris@0 13 /** @returns Parser */
Chris@0 14 abstract protected function getParser(Lexer $lexer);
Chris@0 15
Chris@0 16 /**
Chris@0 17 * @expectedException \PhpParser\Error
Chris@0 18 * @expectedExceptionMessage Syntax error, unexpected EOF on line 1
Chris@0 19 */
Chris@0 20 public function testParserThrowsSyntaxError() {
Chris@0 21 $parser = $this->getParser(new Lexer());
Chris@0 22 $parser->parse('<?php foo');
Chris@0 23 }
Chris@0 24
Chris@0 25 /**
Chris@0 26 * @expectedException \PhpParser\Error
Chris@0 27 * @expectedExceptionMessage Cannot use foo as self because 'self' is a special class name on line 1
Chris@0 28 */
Chris@0 29 public function testParserThrowsSpecialError() {
Chris@0 30 $parser = $this->getParser(new Lexer());
Chris@0 31 $parser->parse('<?php use foo as self;');
Chris@0 32 }
Chris@0 33
Chris@0 34 /**
Chris@0 35 * @expectedException \PhpParser\Error
Chris@0 36 * @expectedExceptionMessage Unterminated comment on line 1
Chris@0 37 */
Chris@0 38 public function testParserThrowsLexerError() {
Chris@0 39 $parser = $this->getParser(new Lexer());
Chris@0 40 $parser->parse('<?php /*');
Chris@0 41 }
Chris@0 42
Chris@0 43 public function testAttributeAssignment() {
Chris@13 44 $lexer = new Lexer([
Chris@13 45 'usedAttributes' => [
Chris@0 46 'comments', 'startLine', 'endLine',
Chris@0 47 'startTokenPos', 'endTokenPos',
Chris@13 48 ]
Chris@13 49 ]);
Chris@0 50
Chris@0 51 $code = <<<'EOC'
Chris@0 52 <?php
Chris@0 53 /** Doc comment */
Chris@0 54 function test($a) {
Chris@0 55 // Line
Chris@0 56 // Comments
Chris@0 57 echo $a;
Chris@0 58 }
Chris@0 59 EOC;
Chris@0 60 $code = canonicalize($code);
Chris@0 61
Chris@0 62 $parser = $this->getParser($lexer);
Chris@0 63 $stmts = $parser->parse($code);
Chris@0 64
Chris@13 65 /** @var Stmt\Function_ $fn */
Chris@0 66 $fn = $stmts[0];
Chris@13 67 $this->assertInstanceOf(Stmt\Function_::class, $fn);
Chris@13 68 $this->assertEquals([
Chris@13 69 'comments' => [
Chris@13 70 new Comment\Doc('/** Doc comment */', 2, 6, 1),
Chris@13 71 ],
Chris@0 72 'startLine' => 3,
Chris@0 73 'endLine' => 7,
Chris@0 74 'startTokenPos' => 3,
Chris@0 75 'endTokenPos' => 21,
Chris@13 76 ], $fn->getAttributes());
Chris@0 77
Chris@0 78 $param = $fn->params[0];
Chris@13 79 $this->assertInstanceOf(Node\Param::class, $param);
Chris@13 80 $this->assertEquals([
Chris@0 81 'startLine' => 3,
Chris@0 82 'endLine' => 3,
Chris@0 83 'startTokenPos' => 7,
Chris@0 84 'endTokenPos' => 7,
Chris@13 85 ], $param->getAttributes());
Chris@0 86
Chris@13 87 /** @var Stmt\Echo_ $echo */
Chris@0 88 $echo = $fn->stmts[0];
Chris@13 89 $this->assertInstanceOf(Stmt\Echo_::class, $echo);
Chris@13 90 $this->assertEquals([
Chris@13 91 'comments' => [
Chris@13 92 new Comment("// Line\n", 4, 49, 12),
Chris@13 93 new Comment("// Comments\n", 5, 61, 14),
Chris@13 94 ],
Chris@0 95 'startLine' => 6,
Chris@0 96 'endLine' => 6,
Chris@0 97 'startTokenPos' => 16,
Chris@0 98 'endTokenPos' => 19,
Chris@13 99 ], $echo->getAttributes());
Chris@0 100
Chris@0 101 /** @var \PhpParser\Node\Expr\Variable $var */
Chris@0 102 $var = $echo->exprs[0];
Chris@13 103 $this->assertInstanceOf(Expr\Variable::class, $var);
Chris@13 104 $this->assertEquals([
Chris@0 105 'startLine' => 6,
Chris@0 106 'endLine' => 6,
Chris@0 107 'startTokenPos' => 18,
Chris@0 108 'endTokenPos' => 18,
Chris@13 109 ], $var->getAttributes());
Chris@0 110 }
Chris@0 111
Chris@0 112 /**
Chris@0 113 * @expectedException \RangeException
Chris@0 114 * @expectedExceptionMessage The lexer returned an invalid token (id=999, value=foobar)
Chris@0 115 */
Chris@0 116 public function testInvalidToken() {
Chris@0 117 $lexer = new InvalidTokenLexer;
Chris@0 118 $parser = $this->getParser($lexer);
Chris@0 119 $parser->parse('dummy');
Chris@0 120 }
Chris@0 121
Chris@0 122 /**
Chris@0 123 * @dataProvider provideTestExtraAttributes
Chris@0 124 */
Chris@0 125 public function testExtraAttributes($code, $expectedAttributes) {
Chris@0 126 $parser = $this->getParser(new Lexer);
Chris@0 127 $stmts = $parser->parse("<?php $code;");
Chris@13 128 $node = $stmts[0] instanceof Stmt\Expression ? $stmts[0]->expr : $stmts[0];
Chris@13 129 $attributes = $node->getAttributes();
Chris@0 130 foreach ($expectedAttributes as $name => $value) {
Chris@0 131 $this->assertSame($value, $attributes[$name]);
Chris@0 132 }
Chris@0 133 }
Chris@0 134
Chris@0 135 public function provideTestExtraAttributes() {
Chris@13 136 return [
Chris@13 137 ['0', ['kind' => Scalar\LNumber::KIND_DEC]],
Chris@13 138 ['9', ['kind' => Scalar\LNumber::KIND_DEC]],
Chris@13 139 ['07', ['kind' => Scalar\LNumber::KIND_OCT]],
Chris@13 140 ['0xf', ['kind' => Scalar\LNumber::KIND_HEX]],
Chris@13 141 ['0XF', ['kind' => Scalar\LNumber::KIND_HEX]],
Chris@13 142 ['0b1', ['kind' => Scalar\LNumber::KIND_BIN]],
Chris@13 143 ['0B1', ['kind' => Scalar\LNumber::KIND_BIN]],
Chris@13 144 ['[]', ['kind' => Expr\Array_::KIND_SHORT]],
Chris@13 145 ['array()', ['kind' => Expr\Array_::KIND_LONG]],
Chris@13 146 ["'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]],
Chris@13 147 ["b'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]],
Chris@13 148 ["B'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]],
Chris@13 149 ['"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]],
Chris@13 150 ['b"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]],
Chris@13 151 ['B"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]],
Chris@13 152 ['"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]],
Chris@13 153 ['b"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]],
Chris@13 154 ['B"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]],
Chris@13 155 ["<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']],
Chris@13 156 ["<<<STR\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']],
Chris@13 157 ["<<<\"STR\"\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']],
Chris@13 158 ["b<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']],
Chris@13 159 ["B<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']],
Chris@13 160 ["<<< \t 'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']],
Chris@13 161 ["<<<'\xff'\n\xff\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => "\xff"]],
Chris@13 162 ["<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']],
Chris@13 163 ["b<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']],
Chris@13 164 ["B<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']],
Chris@13 165 ["<<< \t \"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']],
Chris@13 166 ["die", ['kind' => Expr\Exit_::KIND_DIE]],
Chris@13 167 ["die('done')", ['kind' => Expr\Exit_::KIND_DIE]],
Chris@13 168 ["exit", ['kind' => Expr\Exit_::KIND_EXIT]],
Chris@13 169 ["exit(1)", ['kind' => Expr\Exit_::KIND_EXIT]],
Chris@13 170 ["?>Foo", ['hasLeadingNewline' => false]],
Chris@13 171 ["?>\nFoo", ['hasLeadingNewline' => true]],
Chris@13 172 ["namespace Foo;", ['kind' => Stmt\Namespace_::KIND_SEMICOLON]],
Chris@13 173 ["namespace Foo {}", ['kind' => Stmt\Namespace_::KIND_BRACED]],
Chris@13 174 ["namespace {}", ['kind' => Stmt\Namespace_::KIND_BRACED]],
Chris@13 175 ];
Chris@0 176 }
Chris@0 177 }
Chris@0 178
Chris@13 179 class InvalidTokenLexer extends Lexer
Chris@13 180 {
Chris@13 181 public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) : int {
Chris@0 182 $value = 'foobar';
Chris@0 183 return 999;
Chris@0 184 }
Chris@0 185 }