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/"; +}