diff vendor/nikic/php-parser/test/PhpParser/CodeParsingTest.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
line wrap: on
line diff
--- a/vendor/nikic/php-parser/test/PhpParser/CodeParsingTest.php	Fri Feb 23 15:52:07 2018 +0000
+++ b/vendor/nikic/php-parser/test/PhpParser/CodeParsingTest.php	Mon Apr 23 09:33:26 2018 +0100
@@ -1,7 +1,10 @@
-<?php
+<?php declare(strict_types=1);
 
 namespace PhpParser;
 
+use PhpParser\Node\Expr;
+use PhpParser\Node\Stmt;
+
 require_once __DIR__ . '/CodeTestAbstract.php';
 
 class CodeParsingTest extends CodeTestAbstract
@@ -16,30 +19,42 @@
             $modes = [];
         }
 
-
-        $lexer = new Lexer\Emulative(array('usedAttributes' => array(
-            'startLine', 'endLine', 'startFilePos', 'endFilePos', 'comments'
-        )));
-        $parser5 = new Parser\Php5($lexer);
-        $parser7 = new Parser\Php7($lexer);
-
-        $dumpPositions = isset($modes['positions']);
-        $output5 = $this->getParseOutput($parser5, $code, $dumpPositions);
-        $output7 = $this->getParseOutput($parser7, $code, $dumpPositions);
+        list($parser5, $parser7) = $this->createParsers($modes);
+        list($stmts5, $output5) = $this->getParseOutput($parser5, $code, $modes);
+        list($stmts7, $output7) = $this->getParseOutput($parser7, $code, $modes);
 
         if (isset($modes['php5'])) {
             $this->assertSame($expected, $output5, $name);
             $this->assertNotSame($expected, $output7, $name);
-        } else if (isset($modes['php7'])) {
+        } elseif (isset($modes['php7'])) {
             $this->assertNotSame($expected, $output5, $name);
             $this->assertSame($expected, $output7, $name);
         } else {
             $this->assertSame($expected, $output5, $name);
             $this->assertSame($expected, $output7, $name);
         }
+
+        $this->checkAttributes($stmts5);
+        $this->checkAttributes($stmts7);
     }
 
-    private function getParseOutput(Parser $parser, $code, $dumpPositions) {
+    public function createParsers(array $modes) {
+        $lexer = new Lexer\Emulative(['usedAttributes' => [
+            'startLine', 'endLine',
+            'startFilePos', 'endFilePos',
+            'startTokenPos', 'endTokenPos',
+            'comments'
+        ]]);
+
+        return [
+            new Parser\Php5($lexer),
+            new Parser\Php7($lexer),
+        ];
+    }
+
+    private function getParseOutput(Parser $parser, $code, array $modes) {
+        $dumpPositions = isset($modes['positions']);
+
         $errors = new ErrorHandler\Collecting;
         $stmts = $parser->parse($code, $errors);
 
@@ -53,7 +68,7 @@
             $output .= $dumper->dump($stmts, $code);
         }
 
-        return canonicalize($output);
+        return [$stmts, canonicalize($output)];
     }
 
     public function provideTestParse() {
@@ -67,4 +82,39 @@
             return $e->getMessage();
         }
     }
+
+    private function checkAttributes($stmts) {
+        if ($stmts === null) {
+            return;
+        }
+
+        $traverser = new NodeTraverser();
+        $traverser->addVisitor(new class extends NodeVisitorAbstract {
+            public function enterNode(Node $node) {
+                $startLine = $node->getStartLine();
+                $endLine = $node->getEndLine();
+                $startFilePos = $node->getStartFilePos();
+                $endFilePos = $node->getEndFilePos();
+                $startTokenPos = $node->getStartTokenPos();
+                $endTokenPos = $node->getEndTokenPos();
+                if ($startLine < 0 || $endLine < 0 ||
+                    $startFilePos < 0 || $endFilePos < 0 ||
+                    $startTokenPos < 0 || $endTokenPos < 0
+                ) {
+                    throw new \Exception('Missing location information on ' . $node->getType());
+                }
+
+                if ($endLine < $startLine ||
+                    $endFilePos < $startFilePos ||
+                    $endTokenPos < $startTokenPos
+                ) {
+                    // Nops and error can have inverted order, if they are empty
+                    if (!$node instanceof Stmt\Nop && !$node instanceof Expr\Error) {
+                        throw new \Exception('End < start on ' . $node->getType());
+                    }
+                }
+            }
+        });
+        $traverser->traverse($stmts);
+    }
 }