[projects/buildlogs] Escaping, pdo etc.
arekm
arekm at pld-linux.org
Mon Apr 20 16:14:57 CEST 2026
commit f7fe2a12964780d21b5dbb6d9e70bf835a676d2c
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date: Sat Apr 11 03:22:19 2026 +0200
Escaping, pdo etc.
helpers/buildlogs-inotify-mover.sh | 16 +-
helpers/buildlogs-mover.sh | 72 ++--
helpers/install-buildlogs-tree.sh | 25 +-
index.php | 704 ++++++++++++++++++++++--------------
pld-buildlogs/scripts/addlog.php | 120 ++++--
pld-buildlogs/scripts/migration.php | 141 +++++---
6 files changed, 653 insertions(+), 425 deletions(-)
---
diff --git a/helpers/buildlogs-inotify-mover.sh b/helpers/buildlogs-inotify-mover.sh
index 3b0d324..e7db89f 100644
--- a/helpers/buildlogs-inotify-mover.sh
+++ b/helpers/buildlogs-inotify-mover.sh
@@ -1,14 +1,14 @@
#!/bin/sh
+set -eu
root="/home/services/ftpd/buildlogs"
-if test -f /etc/buildlogs-mover.conf ; then
- . /etc/buildlogs-mover.conf
+if [ -f /etc/buildlogs-mover.conf ]; then
+ . /etc/buildlogs-mover.conf
fi
-
-inotifywait -q -m -r -e move $root/*/*/.new | \
- while read path change file; do
- [ "$change" != "MOVED_TO" ] && continue
- /bin/su - ftp -s /bin/sh -c "/home/services/buildlogs/buildlogs-mover.sh"
- done
+inotifywait -q -m -r -e move "$root"/*/*/.new | \
+while IFS= read -r path change file; do
+ [ "$change" != "MOVED_TO" ] && continue
+ /bin/su - ftp -s /bin/sh -c "/home/services/buildlogs/buildlogs-mover.sh"
+done
diff --git a/helpers/buildlogs-mover.sh b/helpers/buildlogs-mover.sh
index bd917ba..32595ea 100644
--- a/helpers/buildlogs-mover.sh
+++ b/helpers/buildlogs-mover.sh
@@ -13,52 +13,54 @@
# Note that we look for root/*/*/.new/*.info, so don't place any additional
# directories there.
+set -eu
+
root="/home/services/ftpd/buildlogs"
ADDLOG="/home/services/httpd/html/pld-buildlogs/scripts/addlog.php"
-if test -f /etc/buildlogs-mover.conf ; then
- . /etc/buildlogs-mover.conf
+if [ -f /etc/buildlogs-mover.conf ]; then
+ . /etc/buildlogs-mover.conf
fi
-for n in $root/*/*/.new ; do
- if test ! -d $n ; then
- echo "$n doesn't exists or ain't directory"
+# Ensure at least one .new dir exists. If the glob doesn't match anything,
+# find will return no results and the script exits gracefully.
+set +e
+first=$(find "$root" -mindepth 3 -maxdepth 3 -type d -name '.new' | head -n 1)
+set -e
+if [ -z "$first" ]; then
+ echo "no .new directories found under $root" >&2
exit 1
- fi
- break # don't check all
-done
+fi
-handle_info () {
- info="$1"
- info_val="$(cat "$info" 2>/dev/null)"
- if echo "$info_val" | grep -q '^END$' ; then
+handle_info() {
+ info="$1"
+ info_val=$(cat "$info" 2>/dev/null) || return 0
+ echo "$info_val" | grep -q '^END$' || return 0
status=$(echo "$info_val" | grep '^Status:' | sed -e 's/.*: *//')
- case $status in
- OK ) s=OK ;;
- FAIL* ) s=FAIL ;;
- * )
- # this script is run from cron, so this should go through mail
- # to admin
- echo "bad buildlog status: $status in $info:" 1>&2
- echo "#v+" 1>&2
- echo "$info_val" 1>&2
- echo "#v-" 1>&2
- rm "$info" 2>/dev/null
- return
- ;;
+ case "$status" in
+ OK) s=OK ;;
+ FAIL*) s=FAIL ;;
+ *)
+ {
+ echo "bad buildlog status: $status in $info:"
+ echo "#v+"
+ echo "$info_val"
+ echo "#v-"
+ } >&2
+ rm -f "$info"
+ return 0
+ ;;
esac
- archdir="$(dirname "$(dirname "$info")")"
+ archdir=$(dirname "$(dirname "$info")")
file=$(basename "$info" .info)
- if test -f "$archdir/.new/$file"; then
- mv -f "$archdir/.new/$file" "$archdir/$s/$file"
- $ADDLOG "$archdir/$s/$file"
- rm "$info" 2>/dev/null
+ if [ -f "$archdir/.new/$file" ]; then
+ mv -f "$archdir/.new/$file" "$archdir/$s/$file"
+ "$ADDLOG" "$archdir/$s/$file"
+ rm -f "$info"
fi
- fi
}
-for info in $root/*/*/.new/*.info ; do
- if test -f "$info" ; then
- handle_info "$info"
- fi
+find "$root" -mindepth 4 -maxdepth 4 -type f -name '*.info' -path '*/.new/*' | \
+while IFS= read -r info; do
+ [ -f "$info" ] && handle_info "$info"
done
diff --git a/helpers/install-buildlogs-tree.sh b/helpers/install-buildlogs-tree.sh
index 3873710..ef176ce 100644
--- a/helpers/install-buildlogs-tree.sh
+++ b/helpers/install-buildlogs-tree.sh
@@ -1,20 +1,21 @@
#!/bin/sh
# create directories needed for buildlogs
-if [ "$1" = "" ] ; then
- echo "usage: $0 dir"
- exit 1
+set -eu
+
+if [ -z "${1:-}" ]; then
+ echo "usage: $0 dir" >&2
+ exit 1
fi
-mk ()
-{
- for d in "$@" ; do
- mkdir -p $d/{.new,OK,prevOK,FAIL}
- done
+mk() {
+ for d in "$@"; do
+ mkdir -p "$d/.new" "$d/OK" "$d/prevOK" "$d/FAIL"
+ done
}
-cd "$1" || exit 1
+cd "$1"
-mk ac/{i{3,5,6}86,athlon,sparc,ppc,alpha,SRPMS}
-mk ra/{i{3,5,6}86,sparc,ppc,alpha,SRPMS}
-mk nest/{i{3,5,6}86,alpha,ppc,athlon,SRPMS}
+mk ac/i386 ac/i586 ac/i686 ac/athlon ac/sparc ac/ppc ac/alpha ac/SRPMS
+mk ra/i386 ra/i586 ra/i686 ra/sparc ra/ppc ra/alpha ra/SRPMS
+mk nest/i386 nest/i586 nest/i686 nest/alpha nest/ppc nest/athlon nest/SRPMS
diff --git a/index.php b/index.php
index 8d01e7b..c3fd3b1 100644
--- a/index.php
+++ b/index.php
@@ -1,117 +1,191 @@
<?php
-if (!function_exists("ob_gzhandler"))
- die("ob_gzhandler function is missing - install php zlib module");
+declare(strict_types=1);
+if (!function_exists("ob_gzhandler")) {
+ http_response_code(500);
+ die("ob_gzhandler function is missing - install php zlib module");
+}
ob_start("ob_gzhandler", 1);
+
+header("X-Content-Type-Options: nosniff");
+header("X-Frame-Options: DENY");
+header("Referrer-Policy: no-referrer-when-downgrade");
+header(
+ "Content-Security-Policy: "
+ . "default-src 'self'; "
+ . "img-src 'self' data:; "
+ . "style-src 'self' 'unsafe-inline'; "
+ . "script-src 'self' 'unsafe-inline'; "
+ . "object-src 'none'; "
+ . "frame-ancestors 'none'"
+);
+
+function h(?string $s): string {
+ return htmlspecialchars($s ?? '', ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8');
+}
+
+function validate_identifier(?string $v): ?string {
+ if ($v === null || $v === '') return null;
+ if (strlen($v) > 64) return null;
+ if (!preg_match('/^[A-Za-z0-9][A-Za-z0-9_.+-]*$/', $v)) return null;
+ return $v;
+}
+
+function safe_log_path(string $root, string $relative): ?string {
+ $root_real = realpath($root);
+ if ($root_real === false) return null;
+ $full = $root_real . '/' . $relative;
+ $full_real = realpath($full);
+ if ($full_real === false) return null;
+ if (strncmp($full_real, $root_real . '/', strlen($root_real) + 1) !== 0) {
+ return null;
+ }
+ return $full_real;
+}
+
+function like_escape(string $s): string {
+ // Escape SQL LIKE wildcards. The LIKE clause must specify ESCAPE '\\'.
+ return str_replace(['\\', '%', '_'], ['\\\\', '\\%', '\\_'], $s);
+}
+
+function one_item(string $h, string $t): void {
+ echo "<tr><td bgcolor=\"#ccccff\">$h:</td>".
+ "<td bgcolor=\"#cccccc\">$t</td></tr>";
+}
+
+function href_tag(string $url_attr, string $body): string {
+ return '<a href="' . $url_attr . '">' . $body . '</a>';
+}
+
$buildlogs_server = "buildlogs.pld-linux.org";
$url = "index.php";
-$fail_or_ok = array( "FAIL", "OK" );
-/*
-$database = 'sqlite:/home/services/ftp/buildlogs2.db';
-$root_directory = "/home/services/ftp/pub/pld-buildlogs";
-*/
+$fail_or_ok = ["FAIL", "OK"];
// $database, $root_directory and others are taken from buildlogs.inc
include('buildlogs.inc');
-/* It should be set */
-
-$langs["en_US"]["charset"]="ISO-8859-1";
-$langs["pl_PL"]["charset"]="ISO-8859-2";
-
-$lang="en_US";
-$lang_detected="";
-if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"]))
-{
- $rows=explode(";",$_SERVER["HTTP_ACCEPT_LANGUAGE"]);
- $rows=explode(",",$rows[0]);
- $lang_detected=rtrim($rows[0]);
-} else if (preg_match("/opera/i",$_SERVER["HTTP_USER_AGENT"]))
-{
- $lang_detected=preg_replace("/.*\[(.*)\].*/i","\\1",$_SERVER["HTTP_USER_AGENT"]);
+session_set_cookie_params([
+ 'lifetime' => 0,
+ 'path' => '/',
+ 'httponly' => true,
+ 'samesite' => 'Lax',
+ 'secure' => !empty($_SERVER['HTTPS']),
+]);
+session_start();
+
+$langs = [
+ 'en_US' => ['charset' => 'UTF-8'],
+ 'pl_PL' => ['charset' => 'UTF-8'],
+];
+
+$lang = 'en_US';
+$lang_detected = '';
+if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) {
+ $rows = explode(";", $_SERVER["HTTP_ACCEPT_LANGUAGE"]);
+ $rows = explode(",", $rows[0]);
+ $lang_detected = rtrim($rows[0]);
+} elseif (isset($_SERVER["HTTP_USER_AGENT"]) && preg_match("/opera/i", $_SERVER["HTTP_USER_AGENT"])) {
+ $lang_detected = preg_replace("/.*\[(.*)\].*/i", "\\1", $_SERVER["HTTP_USER_AGENT"]);
}
+$lang_detected = preg_replace("/^pl$/i", "pl_PL", $lang_detected);
-// FIXME - some array
-$lang_detected=preg_replace("/^pl$/i","pl_PL",$lang_detected);
-
-if (isset($lang_detected) && isset($langs[$lang_detected]))
-{
- $lang=$lang_detected;
+if ($lang_detected !== '' && isset($langs[$lang_detected])) {
+ $lang = $lang_detected;
}
-if (isset($_GET["lang"]))$_SESSION["lang"]=$_GET["lang"];
-if (isset($_SESSION["lang"]))$lang=$_SESSION["lang"];
+if (isset($_GET["lang"]) && isset($langs[$_GET["lang"]])) {
+ $_SESSION["lang"] = $_GET["lang"];
+}
+if (isset($_SESSION["lang"]) && isset($langs[$_SESSION["lang"]])) {
+ $lang = $_SESSION["lang"];
+}
putenv("LANG=$lang");
-setlocale(LC_ALL,$lang);
-bindtextdomain("messages","locale");
+setlocale(LC_ALL, $lang);
+bindtextdomain("messages", "locale");
textdomain("messages");
-if (isset($_GET["dist"]) && isset($_GET["arch"]))
-{
- $dist = $_GET["dist"];
- $dist = basename(htmlspecialchars($dist, ENT_QUOTES, 'UTF-8'));
- $arch = $_GET["arch"];
- $arch = basename(htmlspecialchars($arch, ENT_QUOTES, 'UTF-8'));
+// Centralized input parsing. Every user-facing variable is validated here.
+$dist = validate_identifier($_GET["dist"] ?? $_POST["dist"] ?? null);
+if ($dist !== null) {
+ $dist = basename($dist);
+ $dist = validate_identifier($dist);
}
-if (isset($_POST["dist"])) {
- $dist = $_POST["dist"];
- $dist = basename(htmlspecialchars($dist, ENT_QUOTES, 'UTF-8'));
+$arch = validate_identifier($_GET["arch"] ?? $_POST["arch"] ?? null);
+if ($arch !== null) {
+ $arch = basename($arch);
+ $arch = validate_identifier($arch);
+ if ($arch === 'src') {
+ $arch = 'SRPMS';
+ }
}
-if (isset($_POST["arch"])) {
- $arch = $_POST["arch"];
- $arch = basename(htmlspecialchars($arch, ENT_QUOTES, 'UTF-8'));
+$name = null;
+$name_url = '';
+if (isset($_GET["name"])) {
+ $raw_name = basename((string)$_GET["name"]);
+ $name = validate_identifier($raw_name);
+ if ($name !== null) {
+ $name_url = urlencode($name);
+ }
}
-if (isset($_GET["name"])) {
- $name_url = urlencode($_GET["name"]);
- $name = $_GET["name"];
- $name = basename(htmlspecialchars($name, ENT_QUOTES, 'UTF-8'));
-}
-
-if (isset($_GET["ok"]))$ok=(int)$_GET["ok"];
-else $ok="";
-if (isset($_GET["ns"]))$ns=(int)$_GET["ns"];
-else $ns="";
-if (isset($_GET["cnt"]))$cnt=(int)$_GET["cnt"];
-else $cnt = 50;
-if (isset($_GET["action"])) {
- $action = $_GET["action"];
- $action = htmlspecialchars($action, ENT_QUOTES, 'UTF-8');
-} else
- $action="";
-if (isset($_GET["off"]))$off=(int)$_GET["off"];
-else $off = 0;
+$id = null;
if (isset($_GET["id"])) {
- $id = $_GET["id"];
- $id = htmlspecialchars($id, ENT_QUOTES, 'UTF-8');
+ $raw_id = basename((string)$_GET["id"]);
+ $id = validate_identifier($raw_id);
}
-if (isset($_POST["str"])) {
- $str = $_POST["str"];
- $str = htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
+$ok_raw = $_GET["ok"] ?? null;
+if ($ok_raw === null || $ok_raw === '') {
+ $ok = '';
+} else {
+ $ok = (int)$ok_raw;
+ if ($ok !== 0 && $ok !== 1) {
+ $ok = 0;
+ }
}
-if (isset($_POST["action"])) {
- $action = $_POST["action"];
- $action = htmlspecialchars($action, ENT_QUOTES, 'UTF-8');
+
+$ns_raw = $_GET["ns"] ?? null;
+if ($ns_raw === null || $ns_raw === '') {
+ $ns = '';
+} else {
+ $ns = (int)$ns_raw;
+ if ($ns < 0 || $ns > 2) {
+ $ns = 0;
+ }
}
-if (isset($arch) && $arch == "src")
- $arch = "SRPMS";
+$cnt = isset($_GET["cnt"]) ? (int)$_GET["cnt"] : 50;
+if ($cnt < 1) $cnt = 1;
+if ($cnt > 500) $cnt = 500;
+
+$off = isset($_GET["off"]) ? (int)$_GET["off"] : 0;
+if ($off < 0) $off = 0;
+
+$ACTION_WHITELIST = ['', 'text', 'tail', 'qa', 'qatxt', 'sqa', 'adv_search'];
+$action_raw = $_POST["action"] ?? $_GET["action"] ?? '';
+$action = in_array($action_raw, $ACTION_WHITELIST, true) ? $action_raw : '';
+
+$str = '';
+if (isset($_POST["str"])) {
+ $str_raw = (string)$_POST["str"];
+ if (strlen($str_raw) <= 200 && mb_check_encoding($str_raw, 'UTF-8')
+ && !preg_match('/[\x00-\x1F\x7F]/', $str_raw)) {
+ $str = $str_raw;
+ }
+}
function myheader()
{
-echo '<' . '?xml version="1.0" encoding="' . _("ISO-8859-1") .'"?' . ">\n";
-echo '<' . '?xml-stylesheet href="#internalStyle" type="text/css"?' . ">\n";
+ header("Content-Type: text/html; charset=UTF-8");
?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
+<!DOCTYPE html>
+<html lang="en">
<head>
<title>PLD Build Logs</title>
- <?php echo '<meta http-equiv="Content-type" content="text/html; charset=' . _("ISO-8859-1") .'"/>' ."\n";?>
+ <meta charset="UTF-8">
<style type="text/css"><!--
A { text-decoration: none; }
A:hover { text-decoration: underline; }
@@ -189,22 +263,24 @@ function list_logs()
'cnt' => $cnt);
$big_url = $url . '?' . http_build_query($query_data);
+ $dist_arch = h($dist . '/' . $arch);
if ($ok == 1) {
- echo "<h1>"._("Listing of")." $dist/$arch/OK "
- ."(<a href=\"$big_url&ok=0\">"._("fail")."</a>)</h1>\n";
+ echo "<h1>"._("Listing of")." $dist_arch/OK "
+ ."(<a href=\"" . h($big_url) . "&ok=0\">"._("fail")."</a>)</h1>\n";
} else {
- echo "<h1>"._("Listing of")." $dist/$arch/FAIL "
- ."(<a href=\"$big_url&ok=1\">"._("ok")."</a>)</h1>\n";
+ echo "<h1>"._("Listing of")." $dist_arch/FAIL "
+ ."(<a href=\"" . h($big_url) . "&ok=1\">"._("ok")."</a>)</h1>\n";
}
echo "<div align=\"center\"><table cols=\"4\" border=\"0\" cellspacing=\"1\" ".
"cellpadding=\"3\" bgcolor=\"#000000\" width=\"90%\">\n";
+ $big_url_esc = h($big_url);
echo "<tr><th bgcolor=\"#CCCCFF\" align=\"right\" width=\"1%\">"._("No.")."</th>".
"<th bgcolor=\"#CCCCFF\" align=\"left\" width=\"80%\">"._("Log File").
- "[<a href=\"$big_url&ns=1\">"._("sort")."</a>]</th>".
+ "[<a href=\"$big_url_esc&ns=1\">"._("sort")."</a>]</th>".
"<th bgcolor=\"#CCCCFF\" align=\"right\" width=\"15%\">"._("Size")."</th> ".
"<th bgcolor=\"#CCCCFF\" align=\"left\">"._("Age").
- "[<a href=\"$big_url&ns=0\">"._("sort")."</a>]</th>".
+ "[<a href=\"$big_url_esc&ns=0\">"._("sort")."</a>]</th>".
"</tr>";
if ($ns != 1) $ns = 0;
@@ -227,12 +303,12 @@ function list_logs()
$now = time();
$i = $off;
$stmt = $dbh->prepare($query);
- $stmt->bindParam(':dist', $dist, PDO::PARAM_STR);
- $stmt->bindParam(':arch', $arch, PDO::PARAM_STR);
- $stmt->bindParam(':ok', $ok, PDO::PARAM_INT);
- $stmt->bindParam(':limitnr', $cnt, PDO::PARAM_INT);
- $stmt->bindParam(':offset', $off, PDO::PARAM_INT);
- $stmt->execute([$dist, $arch, $ok, $cnt, $off]);
+ $stmt->bindValue(':dist', $dist, PDO::PARAM_STR);
+ $stmt->bindValue(':arch', $arch, PDO::PARAM_STR);
+ $stmt->bindValue(':ok', $ok, PDO::PARAM_INT);
+ $stmt->bindValue(':limitnr', $cnt, PDO::PARAM_INT);
+ $stmt->bindValue(':offset', $off, PDO::PARAM_INT);
+ $stmt->execute();
while ($row = $stmt->fetch()) {
$name = $row["name"];
$id = $row["id"];
@@ -249,14 +325,14 @@ function list_logs()
$t /= 60;
if ($t >= 24) {
$t /= 24;
- $t = round($t);
+ $t = (int)round($t);
$t = $t . " " . ngettext("day","days",$t);
} else {
- $t = round($t);
+ $t = (int)round($t);
$t = $t . " " . ngettext("hour","hours",$t);
}
} else {
- $t = round($t);
+ $t = (int)round($t);
$t = $t . " " . ngettext("minute","minutes",$t);
}
$url_data = array(
@@ -265,13 +341,13 @@ function list_logs()
'ok' => $ok,
'name' => $name_url,
'id' => $id);
- $u = $url . '?' . http_build_query($url_data);
+ $u = h($url . '?' . http_build_query($url_data));
echo "<tr><td bgcolor=\"#CCCCCC\" align=\"right\">".($i+1).".</td>".
- "<td bgcolor=\"#CCCCCC\"><a href=\"$u\">".htmlspecialchars($f, ENT_QUOTES, 'UTF-8')."</a> ".
+ "<td bgcolor=\"#CCCCCC\"><a href=\"$u\">" . h($f) . "</a> ".
"[<a href=\"$u&action=text\">"._("text")."</a> | ".
"<a href=\"$u&action=tail\">"._("tail")."</a>]".
"</td><td bgcolor=\"#CCCCCC\" align=\"right\">".
- "$s</td><td bgcolor=\"#CCCCCC\">$t</td></tr>\n";
+ h((string)$s)."</td><td bgcolor=\"#CCCCCC\">$t</td></tr>\n";
$i++;
}
$count = $i - $off;
@@ -286,9 +362,9 @@ function list_logs()
if ($off > 0) {
$noff = $off - $count;
- if ($noff < 0)
+ if ($noff < 0)
$noff = 0;
- $hrefurl = "<a href=\"$big_url&off=$noff\">";
+ $hrefurl = "<a href=\"" . h($big_url) . "&off=$noff\">";
echo "$hrefurl$backarr</a></td><td align=\"left\">$hrefurl$back</a>";
} else {
echo "$backarr</td><td align=\"left\">$back";
@@ -296,8 +372,8 @@ function list_logs()
echo "</td>\n<td align=\"center\">";
- if (isset($dist) && isset($arch)) {
- echo "[<a href=\"$big_url&action=qa\">"._("View <quot>rpm -qa</quot> of builder")."</a>]";
+ if ($dist !== null && $arch !== null) {
+ echo "[<a href=\"" . h($big_url) . "&action=qa\">"._("View <quot>rpm -qa</quot> of builder")."</a>]";
} else {
echo " ";
}
@@ -305,9 +381,9 @@ function list_logs()
echo "</td>\n<td align=right>";
if ($cnt == $count) {
$noff = $off + $cnt;
- if ($noff < 0)
+ if ($noff < 0)
$noff = 0;
- $hrefurl = "<a href=\"$big_url&off=$noff\">";
+ $hrefurl = "<a href=\"" . h($big_url) . "&off=$noff\">";
echo "$hrefurl$forward</a></td><td align=right width=1%>$hrefurl$forwardarr</a>";
} else {
echo "$forward</td><td align=right width=1%>$forwardarr";
@@ -356,50 +432,52 @@ function dump_log($tail)
$df = preg_replace("/.*\/([^\/]*)$/", "\\1", $f);
$df = preg_replace("/\.(bz2|gz)$/", "", $df);
- list($name, $id) = explode(',', $df);
+ $parts = explode(',', $df, 2);
+ $name = $parts[0];
+ $id = $parts[1] ?? '';
+ $name_h = h($name);
if ($name != 'command') {
- $gitweb_url = "http://git.pld-linux.org/?p=packages/$name.git;a=summary";
- $name = "<a href=\"$gitweb_url\">$name</a>";
+ $gitweb_url = "http://git.pld-linux.org/?p=packages/" . rawurlencode($name) . ";a=summary";
+ $name_h = '<a href="' . h($gitweb_url) . '">' . h($name) . '</a>';
}
- echo "<h1>$name <small>$id</small></h1>";
+ echo "<h1>$name_h <small>" . h($id) . "</small></h1>";
echo "<table border=\"0\" cellpadding=\"3\" cellspacing=\"1\" bgcolor=\"#000000\" width=\"100%\">";
- function one_item($h, $t) {
- echo "<tr><td bgcolor=\"#ccccff\">$h:</td>".
- "<td bgcolor=\"#cccccc\">$t</td></tr>";
- }
-
- function href($h, $c) {
- return "<a href=\"$h\">$c</a>";
- }
-
one_item(_("Status"), ($ok == 1 ?
"<font color=\"green\"><b>"._("OK")."</b></font>" :
"<font color=\"red\"><b>"._("Failed")."</b></a>"));
+ $source_url = "https://" . $buildlogs_server . "/pld/" . $f;
one_item(_("Source URL"),
- href("https://$buildlogs_server/pld/$f",
- "https://$buildlogs_server/pld/$f"));
+ href_tag(h($source_url), h($source_url)));
$big_url = "$url?dist=$dist&arch=$arch&ok=$ok&ns=$ns&cnt=$cnt";
$bu = "$big_url&off=$off";
+ $bu_attr = h($bu);
+ $name_url_esc = h((string)$name_url);
+ $id_esc = h(rawurlencode((string)$id));
one_item(_("text/plain URL"),
- href("$bu&name=$name_url&id=$id&action=text",
+ href_tag("{$bu_attr}&name={$name_url_esc}&id={$id_esc}&action=text",
_("View!")));
if ($tail) {
one_item(_("full text"),
- href("$bu&name=$name_url&id=$id",
+ href_tag("{$bu_attr}&name={$name_url_esc}&id={$id_esc}",
_("View!")));
}
- if (isset($dist) && isset($arch)) {
- one_item(_("rpm -qa of builder"), href("$bu&action=qa", _("View!")));
+ if ($dist !== null && $arch !== null) {
+ one_item(_("rpm -qa of builder"), href_tag("{$bu_attr}&action=qa", _("View!")));
} else {
one_item(_("rpm -qa of builder"), _("Not available"));
- }
- one_item("Date", date("Y/m/d H:i:s", filemtime("$root_directory/$f")));
+ }
+ $full_path = safe_log_path($root_directory, $f);
+ if ($full_path !== null && is_file($full_path)) {
+ one_item("Date", date("Y/m/d H:i:s", filemtime($full_path)));
+ } else {
+ one_item("Date", _("unknown"));
+ }
/*
echo "<tr><td>Here:</td><td>" .
"<a href=\"$url?idx=$idx&ok=$ok&id=$id\">".
@@ -412,10 +490,27 @@ function dump_log($tail)
# what can I say beside PHP suxx? how the fuck should I create
# bidirectional pipe? gotta use wget
+ if ($full_path === null) {
+ echo "<p>"._("Log not found")."</p>";
+ echo "</table>";
+ return;
+ }
$filter = get_filter($f);
- $cmd = "$filter '$root_directory/$f'";
- $fd = popen($cmd, "r");
+ $descriptors = [
+ 0 => ['pipe', 'r'],
+ 1 => ['pipe', 'w'],
+ 2 => ['pipe', 'w'],
+ ];
+ $proc = proc_open([$filter, $full_path], $descriptors, $pipes);
+ if (!is_resource($proc)) {
+ echo "<p>"._("Failed to spawn decompressor")."</p>";
+ echo "</table>";
+ return;
+ }
+ fclose($pipes[0]);
+ fclose($pipes[2]);
+ $fd = $pipes[1];
$toc = array();
$err = array();
$first_cut = false;
@@ -429,7 +524,7 @@ function dump_log($tail)
$toc_elem = false;
$err_elem = false;
- $s = htmlspecialchars($s);
+ $s = h($s);
// highlight errors
if (preg_match("/(?:fail|error(s|\sCS\d+)?):/i", $s)) {
$first_cut = true;
@@ -493,7 +588,8 @@ function dump_log($tail)
$err[] = $err_elem;
}
}
- pclose($fd);
+ fclose($fd);
+ proc_close($proc);
// no errors found, no processing found but we are in tail mode
if ($tail && !$first_cut_done && $out_buf_size > 100) {
@@ -547,27 +643,45 @@ function dump_text()
global $root_directory;
global $buildlogs_server;
- header("Content-type: text/plain");
+ header("Content-Type: text/plain; charset=UTF-8");
$f = file_name();
if ($f == false)
return;
+ $full_path = safe_log_path($root_directory, $f);
+ if ($full_path === null || !is_file($full_path)) {
+ http_response_code(404);
+ echo "# log not found\n";
+ return;
+ }
+
echo "# src : https://$buildlogs_server/pld/$f\n";
- echo "# date : " .
- date("Y/m/d H:i:s", filemtime("$root_directory/$f")) . "\n";
+ echo "# date : " . date("Y/m/d H:i:s", filemtime($full_path)) . "\n";
$filter = get_filter($f);
- $cmd = "$filter '$root_directory/$f'";
- $fd = popen($cmd, "r");
- fpassthru($fd);
- pclose($fd);
+ $descriptors = [
+ 0 => ['pipe', 'r'],
+ 1 => ['pipe', 'w'],
+ 2 => ['pipe', 'w'],
+ ];
+ $proc = proc_open([$filter, $full_path], $descriptors, $pipes);
+ if (!is_resource($proc)) {
+ http_response_code(500);
+ echo "# failed to spawn decompressor\n";
+ return;
+ }
+ fclose($pipes[0]);
+ fclose($pipes[2]);
+ fpassthru($pipes[1]);
+ fclose($pipes[1]);
+ proc_close($proc);
}
function list_archs()
{
- global $addr, $url, $cnt,$ok,$ns;
+ global $addr, $url, $cnt, $ok, $ns, $dist, $arch;
if (!isset($cnt))
$cnt = 50;
@@ -576,23 +690,24 @@ function list_archs()
echo "<table width=\"100%\" border=\"0\">\n";
echo "<tr><td bgcolor=\"#cccccc\" nowrap=\"nowrap\">"._("Failed")."</td><td bgcolor=\"#cccccc\">"._("Ok")."</td></tr>\n";
- foreach ($addr as $dist => $ddist) {
+ foreach ($addr as $d => $ddist) {
echo "<tr><td colspan=2 nowrap=\"nowrap\"><hr/></td></tr>\n";
- foreach ($ddist as $arch) {
+ foreach ($ddist as $a) {
+ $da = h($d . '/' . $a);
+ $fail_qs = h("$url?dist=$d&arch=$a&ok=0&cnt=$cnt");
+ $ok_qs = h("$url?dist=$d&arch=$a&ok=1&cnt=$cnt");
echo "<tr><td nowrap=\"nowrap\">".
- "<a href=\"$url?dist=$dist&arch=$arch&ok=0&cnt=$cnt\">
- $dist/$arch</a></td><td nowrap=\"nowrap\">".
- "[<a href=\"$url?dist=$dist&arch=$arch&ok=1&cnt=$cnt\">OK</a>]</td>".
- #"<td>[<a href=\"$url?idx=$i&action=qa\">qa</a>]</td>".
+ "<a href=\"$fail_qs\">$da</a></td><td nowrap=\"nowrap\">".
+ "[<a href=\"$ok_qs\">OK</a>]</td>".
"</tr>\n";
}
}
echo "</table><hr />\n";
echo "<div align=\"center\">";
- echo "<a href=\"$big_url&action=adv_search\">"._("Advanced Search")."</a><br />\n";
-
- echo "<a href=\"$url\">main()</a><hr />\n";
+ echo "<a href=\"" . h($big_url) . "&action=adv_search\">"._("Advanced Search")."</a><br />\n";
+
+ echo "<a href=\"" . h($url) . "\">main()</a><hr />\n";
echo "<a href=\"http://www.pld-linux.org/\"><img src=\"powpld.png\" ".
"alt=\""._("Powered by PLD Linux")."\" border=\"0\" /></a><br />\n" .
"<small>(c) 2002-". date("Y") . " ".
@@ -632,13 +747,13 @@ function list_archs()
echo "</small></div>";
echo "<div align=\"center\"><small>";
- echo "Your IP: " . $_SERVER['REMOTE_ADDR'];
+ echo "Your IP: " . h($_SERVER['REMOTE_ADDR'] ?? '');
echo "</small></div>";
- if (isset($dist) && isset($arch)) {
+ if ($dist !== null && $arch !== null) {
echo "<form action=\"index.php\" method=\"post\">";
- echo "<input type=\"hidden\" name=\"dist\" value=\"$dist\" />";
- echo "<input type=\"hidden\" name=\"arch\" value=\"$arch\" />";
+ echo "<input type=\"hidden\" name=\"dist\" value=\"" . h($dist) . "\" />";
+ echo "<input type=\"hidden\" name=\"arch\" value=\"" . h($arch) . "\" />";
echo "<input type=\"hidden\" name=\"action\" value=\"sqa\" />";
echo "<input type=\"text\" size=\"14\" name=\"str\" /><br />";
echo "<input type=\"submit\" name=\"submit\" value=\""._("Search rpmqa!")."\" />";
@@ -648,12 +763,22 @@ function list_archs()
function get_qa()
{
- global $dist, $arch;
+ global $dist, $arch;
- if (!isset($dist) || !isset($arch))
+ if ($dist === null || $arch === null) {
return false;
- $addr = "http://ftp1.pld-linux.org/dists/$dist/.stat/builder/$dist/rpmqa-$arch.txt";
- return fopen("$addr", "r");
+ }
+ $addr = "https://ftp1.pld-linux.org/dists/" . rawurlencode($dist)
+ . "/.stat/builder/" . rawurlencode($dist)
+ . "/rpmqa-" . rawurlencode($arch) . ".txt";
+ $ctx = stream_context_create([
+ 'http' => [
+ 'method' => 'GET',
+ 'timeout' => 30,
+ 'ignore_errors' => false,
+ ],
+ ]);
+ return @fopen($addr, 'r', false, $ctx);
}
function search_qa()
@@ -661,23 +786,26 @@ function search_qa()
global $url, $str, $dist, $arch;
$f = get_qa();
- echo "<h1>"._("Search results for")." '$str' "._("in")." $dist/$arch</h1>";
+ echo "<h1>"._("Search results for")." '" . h($str) . "' "._("in")." "
+ . h($dist . '/' . $arch) . "</h1>";
start_pre();
- if ($f == 0) {
- echo _("Sorry, cannot open.");
+ if ($f === false) {
+ echo h(_("Sorry, cannot open."));
} else {
- while (($s = fgets($f, 1000)) != false) {
- if (stristr($s, "Query done at:")) {
- echo "rpmqa database from " . strstr($s, ":") . "\n";
+ while (($s = fgets($f, 1000)) !== false) {
+ if (stristr($s, "Query done at:") !== false) {
+ echo "rpmqa database from " . h(strstr($s, ":")) . "\n";
continue;
}
- if (stristr($s, $str))
- echo $s;
+ if ($str !== '' && stristr($s, $str) !== false) {
+ echo h($s);
+ }
}
echo "\n/* EOF */";
+ fclose($f);
}
end_pre();
}
@@ -687,22 +815,29 @@ function dump_qa($plain)
global $url, $dist, $arch;
$f = get_qa();
+ $da = h($dist . '/' . $arch);
if ($plain) {
- header("Content-type: text/plain");
+ header("Content-Type: text/plain; charset=UTF-8");
echo _("# rpm -qa of")." $dist/$arch\n";
} else {
- echo "<h1>"._("rpm -qa of")." $a</h1>";
- echo "<a href=\"$url?dist=$dist&arch=$arch&action=qatxt\">"._("text/plain version")."</a>";
+ echo "<h1>"._("rpm -qa of")." $da</h1>";
+ $qa_url = h($url . '?' . http_build_query([
+ 'dist' => $dist,
+ 'arch' => $arch,
+ 'action' => 'qatxt',
+ ]));
+ echo "<a href=\"$qa_url\">"._("text/plain version")."</a>";
start_pre();
}
- if ($f == 0) {
- echo _("Sorry, cannot open.");
+ if ($f === false) {
+ echo h(_("Sorry, cannot open."));
} else {
- while (($s = fgets($f, 1000)) != false) {
- echo $s;
+ while (($s = fgets($f, 1000)) !== false) {
+ echo $plain ? $s : h($s);
}
+ fclose($f);
}
if (!$plain)
@@ -724,12 +859,11 @@ function adv_search()
"e.checked = document.forms[0].all.checked;\n".
"}\n }\n -->\n </script>\n";
-/* Shut up warnings */
- if (!isset($_POST["n2"])) $_POST["n2"] = "";
- if (!isset($_POST["age1"])) $_POST["age1"] = "";
- if (!isset($_POST["age2"])) $_POST["age2"] = "";
- if (!isset($_POST["size1"])) $_POST["size1"] = "";
- if (!isset($_POST["size2"])) $_POST["size2"] = "";
+ $p_n2 = (string)($_POST["n2"] ?? '');
+ $p_age1 = (string)($_POST["age1"] ?? '');
+ $p_age2 = (string)($_POST["age2"] ?? '');
+ $p_size1 = (string)($_POST["size1"] ?? '');
+ $p_size2 = (string)($_POST["size2"] ?? '');
echo "<form action=\"index.php?action=adv_search\" method=\"post\">";
@@ -737,19 +871,19 @@ function adv_search()
echo "<table border=\"0\">\n";
echo "<tr>\n";
echo "<td>"._("Package name")."</td>\n";
- echo "<td><input type=\"text\" size=\"20\" name=\"n2\" value=\"". $_POST["name"] ."\"/></td>\n";
+ echo "<td><input type=\"text\" size=\"20\" name=\"n2\" value=\"" . h($p_n2) . "\"/></td>\n";
echo "</tr>\n";
echo "<tr>\n";
echo "<td>"._("Days")."</td>\n";
- echo "<td>"._("From").": <input type=\"text\" size=\"20\" name=\"age1\" value=\"". $_POST["age1"] ."\" /></td>\n";
- echo "<td>"._("To").": <input type=\"text\" size=\"20\" name=\"age2\" value=\"". $_POST["age2"] ."\" /></td>\n";
+ echo "<td>"._("From").": <input type=\"text\" size=\"20\" name=\"age1\" value=\"" . h($p_age1) . "\" /></td>\n";
+ echo "<td>"._("To").": <input type=\"text\" size=\"20\" name=\"age2\" value=\"" . h($p_age2) . "\" /></td>\n";
echo "</tr>\n";
echo "<tr>\n";
echo "<td>"._("Size")."</td>\n";
- echo "<td>"._("From").": <input type=\"text\" size=\"20\" name=\"size1\" value=\"". $_POST["size1"] ."\" /></td>\n";
- echo "<td>"._("To").": <input type=\"text\" size=\"20\" name=\"size2\" value=\"". $_POST["size2"] ."\" /></td>\n";
+ echo "<td>"._("From").": <input type=\"text\" size=\"20\" name=\"size1\" value=\"" . h($p_size1) . "\" /></td>\n";
+ echo "<td>"._("To").": <input type=\"text\" size=\"20\" name=\"size2\" value=\"" . h($p_size2) . "\" /></td>\n";
echo "</tr>\n";
echo "<tr>\n";
@@ -762,23 +896,16 @@ function adv_search()
echo "</tr>\n";
$i = 1;
- foreach ($addr as $dist => $ddist) {
- foreach ($ddist as $arch) {
+ foreach ($addr as $d => $ddist) {
+ foreach ($ddist as $a) {
echo "<tr>\n";
- $name="as0_".$i;
- if (!isset($_POST["$name"])) {
- $check = " ";
- } else {
- $check=" checked='checked'";
- }
- echo "<td><input name=\"$name\" id=\"$name\" type=\"checkbox\"$check /><label for=\"$name\">". "$dist/$arch" ."</label></td>\n";
- $name="as1_".$i;
- if (!isset($_POST["$n2"])) {
- $check = " ";
- } else {
- $check=" checked='checked'";
- }
- echo "<td><input name=\"$name\" id=\"$name\" type=\"checkbox\"$check /><label for=\"$name\">". "$dist/$arch" ."</label></td>\n";
+ $label = h($d . '/' . $a);
+ $name = "as0_" . $i;
+ $check = isset($_POST[$name]) ? " checked='checked'" : " ";
+ echo "<td><input name=\"$name\" id=\"$name\" type=\"checkbox\"$check /><label for=\"$name\">$label</label></td>\n";
+ $name = "as1_" . $i;
+ $check = isset($_POST[$name]) ? " checked='checked'" : " ";
+ echo "<td><input name=\"$name\" id=\"$name\" type=\"checkbox\"$check /><label for=\"$name\">$label</label></td>\n";
echo "</tr>\n";
$i++;
}
@@ -790,129 +917,146 @@ function adv_search()
echo "</table>\n";
-// if (isset($_POST["name"]) || isset($_POST["age1"]) || isset($_POST["age2"]) ||
-// isset($_POST["size1"]) || isset($_POST["size2"])
- if (($_POST["n2"]!="") || ($_POST["age1"]!="") || ($_POST["age2"]!="") ||
- ($_POST["size1"]!="") || ($_POST["size2"]!=""))
+ if ($p_n2 !== '' || $p_age1 !== '' || $p_age2 !== '' || $p_size1 !== '' || $p_size2 !== '')
{
- $query = "SELECT log_id, dist, arch, ok, name, size, mtime, id FROM logs WHERE 1 ";
- if ($_POST["n2"] != "") {
- $n = addslashes($_POST["n2"]);
- $query .= "AND name LIKE '$n%' ";
+ $conditions = ['1=1'];
+ $params = [];
+ if ($p_n2 !== '') {
+ $conditions[] = "name LIKE :name_prefix ESCAPE '\\'";
+ $params[':name_prefix'] = like_escape($p_n2) . '%';
}
$now = time();
-
- if ($_POST["age1"] != "") {
- $age = $now - (int)$_POST["age1"] * 24 * 3600;
- $query .= "AND mtime > $age ";
+ if ($p_age1 !== '') {
+ $conditions[] = 'mtime > :age1';
+ $params[':age1'] = $now - ((int)$p_age1) * 24 * 3600;
}
-
- if ($_POST["age2"] != "") {
- $age = $now - (int)$_POST["age2"] * 24 * 3600;
- $query .= "AND mtime < $age ";
+ if ($p_age2 !== '') {
+ $conditions[] = 'mtime < :age2';
+ $params[':age2'] = $now - ((int)$p_age2) * 24 * 3600;
}
-
- if ($_POST["size1"] != "") {
- $size = (int)$_POST["size1"];
- $query .= "AND size > $size ";
+ if ($p_size1 !== '') {
+ $conditions[] = 'size > :size1';
+ $params[':size1'] = (int)$p_size1;
}
-
- if ($_POST["size2"] != "") {
- $size = (int)$_POST["size2"];
- $query .= "AND size < $size ";
+ if ($p_size2 !== '') {
+ $conditions[] = 'size < :size2';
+ $params[':size2'] = (int)$p_size2;
}
- $or = "AND (";
- $i = 1;
- foreach ($addr as $dist => $ddist) {
- foreach ($ddist as $arch) {
- for ($j = 0; $j < 2; $j++) {
- if (isset($_POST["as" . $j . "_" .$i])) {
- $query .= "$or (dist = '$dist' AND arch = '$arch' AND ok = $j)";
- $or = " OR ";
+ $dao_clauses = [];
+ $ii = 1;
+ foreach ($addr as $d => $ddist) {
+ foreach ($ddist as $a) {
+ for ($j = 0; $j < 2; $j++) {
+ if (isset($_POST["as" . $j . "_" . $ii])) {
+ $pd = ":d{$ii}_{$j}";
+ $pa = ":a{$ii}_{$j}";
+ $dao_clauses[] = "(dist = $pd AND arch = $pa AND ok = $j)";
+ $params[$pd] = $d;
+ $params[$pa] = $a;
+ }
}
+ $ii++;
}
- $i++;
- }
}
- if ($or == " OR ") $query .= ")";
-// if (!isset($cnt)) $cnt = 50;
-// if (!isset($off)) $off = 0;
- if (!isset($ns)) $ns = 0;
- switch ($ns) {
- case 0:
- $query .= " ORDER BY mtime DESC";
- break;
- case 1:
- $query .= " ORDER BY name";
- break;
- case 2:
- $query .= " ORDER BY dist, arch, name";
- break;
- }
- $query .= " LIMIT $cnt OFFSET $off ";
+ if ($dao_clauses) {
+ $conditions[] = '(' . implode(' OR ', $dao_clauses) . ')';
+ }
+
+ $order_whitelist = [
+ 0 => 'mtime DESC',
+ 1 => 'name',
+ 2 => 'dist, arch, name',
+ ];
+ $ns_int = is_int($ns) ? $ns : (int)$ns;
+ $order = $order_whitelist[$ns_int] ?? 'mtime DESC';
+
+ $sql = 'SELECT log_id, dist, arch, ok, name, size, mtime, id FROM logs WHERE '
+ . implode(' AND ', $conditions)
+ . ' ORDER BY ' . $order
+ . ' LIMIT :limitnr OFFSET :offset';
try {
- $dbh = new PDO("$database");
+ $dbh = new PDO($database);
+ $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (PDOException $e) {
mydie("new PDO: " . $e->getMessage());
}
- $result = $dbh->query("$query")->fetchAll();
+ $stmt = $dbh->prepare($sql);
+ foreach ($params as $k => $v) {
+ $stmt->bindValue($k, $v);
+ }
+ $stmt->bindValue(':limitnr', $cnt, PDO::PARAM_INT);
+ $stmt->bindValue(':offset', $off, PDO::PARAM_INT);
+ $stmt->execute();
+ $result = $stmt->fetchAll();
- if ($result == FALSE) {
- echo _("Nothing found");
+ if (empty($result)) {
+ echo h(_("Nothing found"));
} else {
+ $big_url_esc = h($big_url);
echo "<table border=\"0\" cellspacing=\"1\" ".
"cellpadding=3 bgcolor=\"#000000\" width=\"90%\">\n";
echo "<tr><th bgcolor=\"#CCCCFF\" align=\"left\" width=\"10%\">"._("Builder").
- "[<a href=\"$big_url&ns=2\">"._("sort")."</a>]</th>";
+ "[<a href=\"$big_url_esc&ns=2\">"._("sort")."</a>]</th>";
echo "<th bgcolor=\"#CCCCFF\" align=\"left\" width=\"60%\">"._("Log File").
- "[<a href=\"$big_url&ns=1\">"._("sort")."</a>]</th>".
- "<th bgcolor=\"#CCCCFF\" align=\"right\" width=\"15%\">"._("Size")."</th> ".
- "<th bgcolor=\"#CCCCFF\" align=\"left\">"._("Age").
- "[<a href=\"$big_url&ns=0\">"._("sort")."</a>]</th>".
- "</th></tr>";
+ "[<a href=\"$big_url_esc&ns=1\">"._("sort")."</a>]</th>".
+ "<th bgcolor=\"#CCCCFF\" align=\"right\" width=\"15%\">"._("Size")."</th> ".
+ "<th bgcolor=\"#CCCCFF\" align=\"left\">"._("Age").
+ "[<a href=\"$big_url_esc&ns=0\">"._("sort")."</a>]</th>".
+ "</th></tr>";
$i = $off;
-// for ($i = $off; $i < $off + $count; $i++) {
foreach ($result as $row) {
- $dist = $row["dist"];
- $arch = $row["arch"];
- $name = $row["name"];
- $name_url = urlencode($name);
- $id = $row["id"];
- $f = $name;
- $t = $now - $row["mtime"];
- $s = $row["size"];
- $t /= 60;
+ $r_dist = (string)$row["dist"];
+ $r_arch = (string)$row["arch"];
+ $r_name = (string)$row["name"];
+ $r_id = (string)$row["id"];
+ $r_ok = (int)$row["ok"];
+ $r_size = (int)$row["size"];
+ $r_mtime = (int)$row["mtime"];
+
+ $t = ($now - $r_mtime) / 60;
if ($t >= 60) {
$t /= 60;
if ($t >= 24) {
$t /= 24;
$t = round($t);
- $t = $t . " " . ngettext("day","days",$t);
+ $t_str = $t . " " . ngettext("day","days",(int)$t);
} else {
$t = round($t);
- $t = $t . " " . ngettext("hour","hours",$t);
+ $t_str = $t . " " . ngettext("hour","hours",(int)$t);
}
} else {
$t = round($t);
- $t = $t . " " . ngettext("minute","minutes",$t);
+ $t_str = $t . " " . ngettext("minute","minutes",(int)$t);
}
-
-// $big_url = "$url?idx=$i&ok=$j&ns=$ns&cnt=$cnt";
- $ok = $row["ok"];
- $u = "$url?dist=$dist&arch=$arch&name=$name_url&ok=$ok&id=$id";
- $b = "$url?dist=$dist&arch=$arch&ok=$ok&ns=$ns&off=$off&cnt=$cnt";
- $builder = "$dist/$arch/". $fail_or_ok[$ok];
+ $u = h($url . '?' . http_build_query([
+ 'dist' => $r_dist,
+ 'arch' => $r_arch,
+ 'name' => $r_name,
+ 'ok' => $r_ok,
+ 'id' => $r_id,
+ ]));
+ $b = h($url . '?' . http_build_query([
+ 'dist' => $r_dist,
+ 'arch' => $r_arch,
+ 'ok' => $r_ok,
+ 'ns' => is_int($ns) ? $ns : 0,
+ 'off' => $off,
+ 'cnt' => $cnt,
+ ]));
+ $builder = h($r_dist . '/' . $r_arch . '/' . $fail_or_ok[$r_ok]);
+
echo "<tr>";
echo "<td bgcolor=\"#CCCCCC\"><a href=\"$b\">$builder</a></td>";
- echo "<td bgcolor=\"#CCCCCC\"><a href=\"$u\">$f</a> ".
- "[<a href=\"$u&action=text\">"._("text")."</a> | ".
- "<a href=\"$u&action=tail\">"._("tail")."</a>]".
- "</td><td bgcolor=\"#CCCCCC\" align=\"right\">".
- "$s</td><td bgcolor=\"#CCCCCC\">$t</td></tr>\n";
- $i++;
+ echo "<td bgcolor=\"#CCCCCC\"><a href=\"$u\">" . h($r_name) . "</a> ".
+ "[<a href=\"$u&action=text\">"._("text")."</a> | ".
+ "<a href=\"$u&action=tail\">"._("tail")."</a>]".
+ "</td><td bgcolor=\"#CCCCCC\" align=\"right\">".
+ h((string)$r_size)."</td><td bgcolor=\"#CCCCCC\">$t_str</td></tr>\n";
+ $i++;
}
echo "</table></div>\n";
diff --git a/pld-buildlogs/scripts/addlog.php b/pld-buildlogs/scripts/addlog.php
index 24dd189..8fc4488 100644
--- a/pld-buildlogs/scripts/addlog.php
+++ b/pld-buildlogs/scripts/addlog.php
@@ -1,55 +1,97 @@
#!/usr/bin/php.cli
<?php
-// $Revision: 1.3 $, $Date: 2009/01/20 07:37:40 $
-/*
-$database = 'sqlite:/home/services/httpd/html/pld-buildlogs/db/buildlogs2.db';
-$root_directory = '/home/services/ftp/pub/pld-buildlogs';
-// $database and $root_directory are taken from buildlogs.inc .
-// parameter: argv[1] - full path to the log file.
-*/
-
-$result = array("FAIL" => 0, "OK" => 1);
+declare(strict_types=1);
+
+$result = ["FAIL" => 0, "OK" => 1];
include('buildlogs.inc');
if (!isset($argv[1])) {
- die("Usage: $argv[0] full_path_to_the_log\n");
+ fwrite(STDERR, "Usage: {$argv[0]} full_path_to_the_log\n");
+ exit(1);
+}
+
+$path = $argv[1];
+
+if (!preg_match("|^" . preg_quote($root_directory, '|')
+ . "/([^/]+)/([^/]+)/([^/]+)/(.+)\\.bz2$|", $path, $matches)) {
+ exit(0);
}
-if (!preg_match("|^$root_directory/(.*)/(.*)/(.*)/(.*)\.bz2$|", $argv[1], $matches))
- exit(0);
-if (preg_match("/^(.*),(.*)$/", $matches[4], $m2)) {
- $name = $m2[1];
- $id = $m2[2];
+$dist_raw = $matches[1];
+$arch_raw = $matches[2];
+$status = $matches[3];
+$basename = $matches[4];
+
+if (preg_match('/^(.*),(.*)$/', $basename, $m2)) {
+ $name_raw = $m2[1];
+ $id_raw = $m2[2];
} else {
- $name = $matches[4];
- $id = "";
+ $name_raw = $basename;
+ $id_raw = '';
}
-$dist = $matches[1];
-$arch = $matches[2];
-$ok = $result[$matches[3]];
-$size = filesize($argv[1]);
-$mtime = filemtime($argv[1]);
-#print "name $name, id $id, dist $dist, arch $arch, ok $ok, size, $size, mtime $mtime\n";
+$identifier_re = '/^[A-Za-z0-9][A-Za-z0-9_.+-]*$/';
+if (!preg_match($identifier_re, $dist_raw)
+ || !preg_match($identifier_re, $arch_raw)
+ || !preg_match($identifier_re, $name_raw)
+ || ($id_raw !== '' && !preg_match($identifier_re, $id_raw))
+ || !isset($result[$status])) {
+ fwrite(STDERR, "skip: invalid identifier in {$path}\n");
+ exit(0);
+}
+
+$ok = $result[$status];
+$size = filesize($path);
+$mtime = filemtime($path);
+if ($size === false || $mtime === false) {
+ fwrite(STDERR, "stat failed: {$path}\n");
+ exit(1);
+}
try {
- $dbh = new PDO("$database");
+ $dbh = new PDO($database);
+ $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (PDOException $e) {
- die ($e->getMessage());
+ fwrite(STDERR, "PDO connect: " . $e->getMessage() . "\n");
+ exit(1);
}
-$result = $dbh->query("SELECT log_id FROM logs WHERE dist = '$dist' AND arch = '$arch' AND name = '$name'"
-." AND id = '$id' LIMIT 1")->fetchAll();
-if (count($result) == 1) {
- foreach ($result as $row) {
- $query = "UPDATE logs SET ok = $ok, size = $size, mtime = $mtime WHERE log_id = $row[log_id]";
- break;
- }
+
+$sel = $dbh->prepare(
+ 'SELECT log_id FROM logs WHERE dist = :dist AND arch = :arch '
+ . 'AND name = :name AND id = :id LIMIT 1'
+);
+$sel->execute([
+ ':dist' => $dist_raw,
+ ':arch' => $arch_raw,
+ ':name' => $name_raw,
+ ':id' => $id_raw,
+]);
+$row = $sel->fetch();
+
+if ($row !== false) {
+ $upd = $dbh->prepare(
+ 'UPDATE logs SET ok = :ok, size = :size, mtime = :mtime '
+ . 'WHERE log_id = :log_id'
+ );
+ $upd->execute([
+ ':ok' => $ok,
+ ':size' => $size,
+ ':mtime' => $mtime,
+ ':log_id' => $row['log_id'],
+ ]);
} else {
- $query = "INSERT INTO logs(dist, arch, ok, name, size, mtime, id) "
- . "VALUES('$dist', '$arch', $ok, '$name', $size, $mtime, '$id')";
-}
-$ile = $dbh->exec("$query");
-if ($ile != 1) {
- print_r($dbh->errorInfo());
+ $ins = $dbh->prepare(
+ 'INSERT INTO logs(dist, arch, ok, name, size, mtime, id) '
+ . 'VALUES(:dist, :arch, :ok, :name, :size, :mtime, :id)'
+ );
+ $ins->execute([
+ ':dist' => $dist_raw,
+ ':arch' => $arch_raw,
+ ':ok' => $ok,
+ ':name' => $name_raw,
+ ':size' => $size,
+ ':mtime' => $mtime,
+ ':id' => $id_raw,
+ ]);
}
-?>
diff --git a/pld-buildlogs/scripts/migration.php b/pld-buildlogs/scripts/migration.php
index 20faa00..b2deedb 100644
--- a/pld-buildlogs/scripts/migration.php
+++ b/pld-buildlogs/scripts/migration.php
@@ -1,68 +1,107 @@
#!/usr/bin/php.cli
<?php
-// $Revision: 1.3 $, $Date: 2009/01/20 07:49:34 $
-/*
-$root_directory = '/home/services/ftp/pub/pld-buildlogs';
-$database = 'sqlite:/home/services/httpd/html/pld-buildlogs/db/buildlogs2.db';
-// $root_directory and $database are taken from buildlogs.inc
-*/
+declare(strict_types=1);
+
include('buildlogs.inc');
if (file_exists($database_file)) {
- unlink($database_file);
+ unlink($database_file);
}
-$query = " CREATE TABLE LOGS(log_id INTEGER PRIMARY KEY, dist TEXT, arch TEXT, ok INTEGER, name TEXT, "
- . "size INTEGER, mtime INTEGER, id TEXT DEFAULT ''); CREATE INDEX IF NOT EXISTS dao_index ON LOGS(dist, arch, ok);";
try {
- $dbhandle = new PDO("$database");
+ $dbh = new PDO($database);
+ $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (PDOException $e) {
- die("new PDO: ". $e->getMessage());
+ fwrite(STDERR, "PDO connect: " . $e->getMessage() . "\n");
+ exit(1);
}
-$result = array("FAIL", "OK");
+$dbh->query(
+ "CREATE TABLE logs(log_id INTEGER PRIMARY KEY, "
+ . "dist TEXT, arch TEXT, ok INTEGER, name TEXT, "
+ . "size INTEGER, mtime INTEGER, id TEXT DEFAULT '')"
+);
+$dbh->query("CREATE INDEX IF NOT EXISTS dao_index ON logs(dist, arch, ok)");
+
+$ins = $dbh->prepare(
+ 'INSERT INTO logs(dist, arch, ok, name, size, mtime, id) '
+ . 'VALUES(:dist, :arch, :ok, :name, :size, :mtime, :id)'
+);
+
+$identifier_re = '/^[A-Za-z0-9][A-Za-z0-9_.+-]*$/';
+$result = ["FAIL", "OK"];
+
+$dbh->beginTransaction();
+$inserted = 0;
+$skipped = 0;
$dh = opendir($root_directory);
-if (!$dh) {
- die("opendir $root_directory");
+if ($dh === false) {
+ fwrite(STDERR, "opendir $root_directory failed\n");
+ exit(1);
}
-while ($dist = readdir($dh)) {
- if ($dist[0] == '.') continue;
- if (!is_dir("$root_directory/$dist")) continue;
- $ah = opendir("$root_directory/$dist");
- if (!$ah) die("opendir $dist");
- while ($arch = readdir($ah)) {
- if ($arch[0] == '.') continue;
- if (!is_dir("$root_directory/$dist/$arch")) continue;
- for ($ok = 0; $ok < 2; $ok++) {
- $directory = "$root_directory/$dist/$arch/" . $result[$ok];
- $sh = opendir($directory);
- if (!$sh) continue;
- while ($file = readdir($sh)) {
- if (preg_match("/^(.*)\.bz2$/", $file, $match)) {
- if (preg_match("/(.*),(.*)/", $match[1], $m2)) {
- $name = $m2[1];
- $id = $m2[2];
- } else {
- $name = $match[1];
- $id = "";
- }
- $f = "$directory/" . $match[0];
- $size = filesize($f);
- $mtime = filemtime($f);
-$query .= " INSERT INTO logs(dist, arch, ok, name, size, mtime, id) "
-. "VALUES('$dist', '$arch', $ok, '$name', $size, $mtime, '$id');";
- }
-
- }
- closedir($sh);
- }
- }
- closedir($ah);
+while (($dist = readdir($dh)) !== false) {
+ if ($dist[0] === '.') continue;
+ if (!is_dir("$root_directory/$dist")) continue;
+ if (!preg_match($identifier_re, $dist)) {
+ $skipped++;
+ continue;
+ }
+ $ah = opendir("$root_directory/$dist");
+ if ($ah === false) {
+ fwrite(STDERR, "opendir $dist failed\n");
+ continue;
+ }
+ while (($arch = readdir($ah)) !== false) {
+ if ($arch[0] === '.') continue;
+ if (!is_dir("$root_directory/$dist/$arch")) continue;
+ if (!preg_match($identifier_re, $arch)) {
+ $skipped++;
+ continue;
+ }
+ for ($ok = 0; $ok < 2; $ok++) {
+ $directory = "$root_directory/$dist/$arch/" . $result[$ok];
+ $sh = @opendir($directory);
+ if ($sh === false) continue;
+ while (($file = readdir($sh)) !== false) {
+ if (!preg_match('/^(.*)\.bz2$/', $file, $match)) continue;
+ if (preg_match('/^(.*),(.*)$/', $match[1], $m2)) {
+ $name = $m2[1];
+ $id = $m2[2];
+ } else {
+ $name = $match[1];
+ $id = '';
+ }
+ if (!preg_match($identifier_re, $name)
+ || ($id !== '' && !preg_match($identifier_re, $id))) {
+ $skipped++;
+ continue;
+ }
+ $f = "$directory/" . $match[0];
+ $size = filesize($f);
+ $mtime = filemtime($f);
+ if ($size === false || $mtime === false) {
+ $skipped++;
+ continue;
+ }
+ $ins->execute([
+ ':dist' => $dist,
+ ':arch' => $arch,
+ ':ok' => $ok,
+ ':name' => $name,
+ ':size' => $size,
+ ':mtime' => $mtime,
+ ':id' => $id,
+ ]);
+ $inserted++;
+ }
+ closedir($sh);
+ }
+ }
+ closedir($ah);
}
closedir($dh);
-$dbhandle->beginTransaction();
-$dbhandle->exec("$query");
-$dbhandle->commit();
-?>
+$dbh->commit();
+fwrite(STDERR, "done: inserted $inserted, skipped $skipped invalid entries\n");
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/projects/buildlogs.git/commitdiff/166f87ba777bdf92412dccf4b6e825ff1e0b4f99
More information about the pld-cvs-commit
mailing list