From 4b83175fcab8caa4f1a863cc654f0d991b6ffb58 Mon Sep 17 00:00:00 2001 From: dweller Date: Tue, 12 Mar 2024 00:50:55 +0200 Subject: disallow injection of args to $manbin via $query --- TODO | 1 - search.php | 122 ++++++++++++++++++++++++++++++++----------------------------- 2 files changed, 65 insertions(+), 58 deletions(-) diff --git a/TODO b/TODO index 408646b..c5d212d 100644 --- a/TODO +++ b/TODO @@ -8,5 +8,4 @@ TODO: Maybe use a default arch to speed up search? Could try to detect arch via TODO: Minify, consolidate TODO: re-export .svgs as plain svg TODO: readable credits in about.html or something -FIXME: it's possible to call man args like -w, dissalow strings that start with -? TODO: add the ifra. configuration scripts (like nginx and php-fpm config) and make it automated diff --git a/search.php b/search.php index 12c1719..234aa9e 100644 --- a/search.php +++ b/search.php @@ -100,79 +100,87 @@ if(!empty($arch)) $arg_section .= " -S ". escapeshellarg($arch); - $found_man = false; - if($action === "man") + /* NOTE: This seems like it's a too ad hoc of a solution, but _theoretically_ escapeshellarg() + * should take care of the rest. I need more testing. + */ + if($query[0] === "-") $query = ltrim($query, "-\n\r\t\v\x00"); + if(!empty($query)) { - $res = exec("$manbin -M $manpath -T html -O fragment,toc $arg_section " - . escapeshellarg($query), $lines, $ret); - if($ret === 0) + $found_man = false; + if($action === "man") { - /* TODO: maybe hardcoding a line isn't such a good idea, but I don't wanna regex the - * whole thing */ - preg_match('/.+.+\((.).*\)<\/span>/iu', $lines[1], $sect); + $res = exec("$manbin -M $manpath -T html -O fragment,toc $arg_section " + . escapeshellarg($query), $lines, $ret); + if($ret === 0) + { + /* TODO: maybe hardcoding a line isn't such a good idea, but I don't wanna regex the + * whole thing */ + preg_match('/.+.+\((.).*\)<\/span>/iu', $lines[1], $sect); - $url = "$root/?query=". urlencode($query) ."&section=". urlencode($sect[1]) - ."&arch=". urlencode($arch) ."&action=lmmtfy"; + $url = "$root/?query=". urlencode($query) ."&section=". urlencode($sect[1]) + ."&arch=". urlencode($arch) ."&action=lmmtfy"; - /* HACK: fucking mandoc just generates tons of useless
s that make stuff - * look horrible. So I just remove it here. - * As you can see, they also decided to pepper the HTML with inline style coz they - * just absolutely hate me, so I strip it too. - */ - for($i = 0; $i < count($lines); $i++) - { - $line = preg_replace('/\/i', '', $lines[$i]); - $line = preg_replace('/style=".*"/i', '', $line); - if(!empty(trim($line))) $lines2[$i] = $line; - } + /* HACK: fucking mandoc just generates tons of useless
s that make stuff + * look horrible. So I just remove it here. + * As you can see, they also decided to pepper the HTML with inline style coz they + * just absolutely hate me, so I strip it too. + */ + for($i = 0; $i < count($lines); $i++) + { + $line = preg_replace('/\/i', '', $lines[$i]); + $line = preg_replace('/style=".*"/i', '', $line); + if(!empty(trim($line))) $lines2[$i] = $line; + } - echo ""; - echo "
". implode(PHP_EOL, $lines2) ."
"; - echo ""; + echo ""; + echo "
". implode(PHP_EOL, $lines2) ."
"; + echo ""; - $found_man = true; + $found_man = true; + } } - } - if(($action === "apropos") || !$found_man) - { - $res = exec("$manbin -M $manpath $arg_section -k " . escapeshellarg($query), $lines, $ret); - if($ret === 0) + if(($action === "apropos") || !$found_man) { - $n = count($lines); - $s = $n > 1 ? "s" : ""; - echo "

Found $n result$s

"; - - foreach($lines as $line) + $res = exec("$manbin -M $manpath $arg_section -k " . escapeshellarg($query), $lines, $ret); + if($ret === 0) { - preg_match('/^((.+)(?:,.+)*)\((.+)\)\s?-\s?(.*)$/Uu', $line, $matches); - $fname = $matches[1]; - $name = $matches[2]; - $fsect = $matches[3]; - $desc = $matches[4]; - $sect = explode(',', $fsect); - $arch = explode('/', end($sect)); - $sect = trim($arch[0]); - $arch = trim(end($arch)); + $n = count($lines); + $s = $n > 1 ? "s" : ""; + echo "

Found $n result$s

"; + + foreach($lines as $line) + { + preg_match('/^((.+)(?:,.+)*)\((.+)\)\s?-\s?(.*)$/Uu', $line, $matches); + $fname = $matches[1]; + $name = $matches[2]; + $fsect = $matches[3]; + $desc = $matches[4]; + $sect = explode(',', $fsect); + $arch = explode('/', end($sect)); + $sect = trim($arch[0]); + $arch = trim(end($arch)); - $descl = strlen($desc); - if($descl > 320) $desc = substr($desc, 0, 320) . "..."; - elseif($descl === 0) $desc = "No synopsis."; + $descl = strlen($desc); + if($descl > 320) $desc = substr($desc, 0, 320) . "..."; + elseif($descl === 0) $desc = "No synopsis."; - $url = "$root/search.php?query=". urlencode($name) ."§ion=". urlencode($sect) - ."&arch=". urlencode($arch) ."&action=man"; + $url = "$root/search.php?query=". urlencode($name) ."§ion=". urlencode($sect) + ."&arch=". urlencode($arch) ."&action=man"; - echo '
'; - echo "
$fname($fsect)
"; - echo "
$desc
"; - echo '
'; + echo '
'; + echo "
$fname($fsect)
"; + echo "
$desc
"; + echo '
'; + } } + else echo "

No results.

"; } - else echo "

No results.

"; } + else echo "

No input = no results.

"; ?>