Commit:    e271f56a71b9ead1ca788e960d239ed99157e088
Author:    Sara Golemon <poll...@php.net>         Sat, 25 Aug 2018 21:22:38 
-0400
Parents:   21128e0fe5699999c17fbf4a5a90de11fd7a935e
Branches:  master

Link:       
http://git.php.net/?p=web/qa.git;a=commitdiff;h=e271f56a71b9ead1ca788e960d239ed99157e088

Log:
Unify branch/revision parameter checking into a single place.

Also fix a bug from FAIL_CRASH detection (looking for wrong file).

Changed paths:
  M  build.php
  M  list_builds.php
  M  reports/reportsfunctions.php


Diff:
diff --git a/build.php b/build.php
index 9c58912..3f1e961 100755
--- a/build.php
+++ b/build.php
@@ -1,22 +1,13 @@
 <?php
 
+include("include/functions.php");
+include("reports/reportsfunctions.php");
+
 $branch = $_GET['branch'] ?? '';
-if ((substr($branch, 0, 3) !== 'PHP') || strpbrk($branch, './\\') !== false) {
-       $branch = "PHP_5_6";
-}
+isValidBranch($branch) or $branch = 'PHP_5_6';
 
 $revision = $_GET['revision'] ?? '';
-if ((substr($revision, 0, 1)!='r') && (strpos($revision, ".") === false)) {
-       // $revision may be an svn ID (i.e. r12345),
-       // or a release version (i.e 7.2.9)
-       $revision = '';
-}
-if (strpbrk($revision, '/\\') !== false) {
-       // Lightweight directory traversal guard
-       $revision = '';
-}
-
-include("include/functions.php");
+isValidRevision($revision) or $revision = '';
 
 $TITLE = htmlentities("PHP: QA: PFTT: $branch: $revision");
 $SITE_UPDATE = date("D M d H:i:s Y T", filectime(__FILE__));
@@ -64,7 +55,7 @@ common_footer();
 
 // Generator function to ennumerate structured data from reports/db
 function genReports(string $type, string $branch, string $revision) {
-       $dir = __DIR__ . "/reports/db/$branch/$revision/";
+       $dir = makeRevisionPath($branch, $revision);
        if (!is_dir($dir)) { return; }
 
        $baseURL = '/reports/db/' . urlencode($branch) . '/' . 
urlencode($revision) . '/';
@@ -80,7 +71,7 @@ function genReports(string $type, string $branch, string 
$revision) {
                        yield [
                                'url' => $baseURL . urlencode($report),
                                'name' => $reportName,
-                               'has_fails_crashes' => 
file_exists("$dir/$reportName.txt"),
+                               'has_fails_crashes' => 
file_exists("$dir/FAIL_CRASH.txt"),
                        ];
                }
        }
diff --git a/list_builds.php b/list_builds.php
index 54d6268..aa0c542 100755
--- a/list_builds.php
+++ b/list_builds.php
@@ -1,12 +1,9 @@
 <?php
 
-$branch = $_GET['branch'] ?? '';
-if ((substr($branch, 0, 3) !== 'PHP') ||
-       (strpbrk($branch, '\\/') !== false)) {
-       $branch = 'PHP_5_6';
-}
-
 include("include/functions.php");
+include("reports/reportsfunctions.php");
+$branch = $_GET['branch'] ?? '';
+isValidBranch($branch) or $branch = 'PHP_5_6';
 
 $TITLE = "PHP: QA: PFTT: $branch";
 $SITE_UPDATE = date("D M d H:i:s Y T", filectime(__FILE__));
@@ -18,7 +15,7 @@ echo '<h1><a href="pftt.php">', htmlentities($branch), 
"</a></h1>\n";
 echo "<p>Choose a PHP revision or build</p>\n";
 
 (function() use ($branch) {
-       $branchdir = __DIR__ . "/reports/db/$branch";
+       $branchdir = makeBranchPath($branch);
        if (!is_dir($branchdir)) { return; }
 
        $revisions = scandir($branchdir);
@@ -41,8 +38,10 @@ echo "<p>Choose a PHP revision or build</p>\n";
        // Output revisions, from most recent to least.
        echo "<table class=\"pftt\">\n";
        foreach ($revisions as $revision => $mtime) {
+               $revpath = makeRevisionPath($branch, $revision);
+               if (!is_dir($revpath)) { continue; }
                $style = 'background: ' .
-                       (is_file("$branchdir/$revision/FAIL_CRASH.txt") ? 
'#ff0000' : '#ccff66');
+                       (is_file("$revpath/FAIL_CRASH.txt") ? '#ff0000' : 
'#ccff66');
                echo "<tr style=\"$style\">";
                echo '<td><a href="build.php?branch=', urlencode($branch),
                     '&revision=', urlencode($revision), '">',
diff --git a/reports/reportsfunctions.php b/reports/reportsfunctions.php
index 38cdba7..63f068a 100644
--- a/reports/reportsfunctions.php
+++ b/reports/reportsfunctions.php
@@ -216,3 +216,47 @@ function format_readable_date($date) {
     }
     return $return." ago";
 }
+
+// In a report/ or pfft script, the 'branch' parameter
+// takes the form PHP_{$major}_{$minor} (i.e. PHP_7_2)
+// or PHP_MASTER, indicating the current master branch
+function isValidBranch(string $branch, bool $verifyExists = true): bool {
+       return ($branch === 'PHP_MASTER') ||
+               preg_match('@^PHP_\d{1,10}_\d{1,10}$@', $branch);
+}
+
+// In a report/ or pftt script, the 'revision' parameter
+// may be either the letter 'r' followed by hexits,
+// indicating a GIT hash (or possibly a SVN revision?)
+// Or they may be a release version (e.g. '7.2.9', '7.3.0-beta2')
+function isValidRevision(string $revision): bool {
+       // 41 characters ought to be enough for any revision (haha)
+       if ((strlen($revision) < 1) || (strlen($revision) > 41)) {
+               return false;
+       }
+
+       // Allow r(HEXIT+) form.
+       if (($revision[0] === 'r') && ctype_xdigit(substr($revision, 1))) {
+               return true;
+       }
+
+       // Allow release version form.
+       if (preg_match('@^\d+\.\d+\.\d+(-alpha\d+|-beta\d+|RC\d+|-dev)?$@i', 
$revision)) {
+               return true;
+       }
+
+       return false;
+}
+
+// Generate a path from a branch name
+function makeBranchPath(string $branch) /* : ?sting */ {
+       if (!isValidBranch($branch)) return null;
+       return __DIR__ . "/db/$branch/";
+}
+
+// Generate a path from a branch and revision
+function makeRevisionPath(string $branch, string $revision) /* : ?string */ {
+       $path = makeBranchPath($branch);
+       if (($path === null) || !isValidRevision($revision)) { return false; }
+       return "$path/$revision/";
+}

Reply via email to