summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordweller <dweller@cabin.digital>2024-03-12 00:50:55 +0200
committerdweller <dweller@cabin.digital>2024-03-12 00:51:12 +0200
commit4b83175fcab8caa4f1a863cc654f0d991b6ffb58 (patch)
tree65e40de4204df881418813880628214c8f7779cc
parent867c582eb42ec8f28c1a5012d43b615df1ef75e1 (diff)
disallow injection of args to $manbin via $query
-rw-r--r--TODO1
-rw-r--r--search.php122
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 class="head-ltitle">.+\((.).*\)<\/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 class="head-ltitle">.+\((.).*\)<\/span>/iu', $lines[1], $sect);
- $url = "$root/?query=". urlencode($query) ."&ampsection=". urlencode($sect[1])
- ."&arch=". urlencode($arch) ."&action=lmmtfy";
+ $url = "$root/?query=". urlencode($query) ."&ampsection=". urlencode($sect[1])
+ ."&arch=". urlencode($arch) ."&action=lmmtfy";
- /* HACK: fucking mandoc just generates tons of useless <br>s that make <code> 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('/\<br.\>/i', '', $lines[$i]);
- $line = preg_replace('/style=".*"/i', '', $line);
- if(!empty(trim($line))) $lines2[$i] = $line;
- }
+ /* HACK: fucking mandoc just generates tons of useless <br>s that make <code> 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('/\<br.\>/i', '', $lines[$i]);
+ $line = preg_replace('/style=".*"/i', '', $line);
+ if(!empty(trim($line))) $lines2[$i] = $line;
+ }
- echo "<nav id='lmmtfy'><div><div>";
- echo " <label for='lmmtfy_url'>LmmtFy URL</label></div>";
- echo " <textarea id='lmmtfy_url' wrap='off' rows='1' readonly>".$url."</textarea>";
- echo " <button id='lmmtfy_copy' class='jsonly'>Copy</button></div></nav>";
- echo "<article class='manpage'>". implode(PHP_EOL, $lines2) ."</article>";
- echo "<script src='/js/copy.js'></script>";
+ echo "<nav id='lmmtfy'><div><div>";
+ echo " <label for='lmmtfy_url'>LmmtFy URL</label></div>";
+ echo " <textarea id='lmmtfy_url' wrap='off' rows='1' readonly>".$url."</textarea>";
+ echo " <button id='lmmtfy_copy' class='jsonly'>Copy</button></div></nav>";
+ echo "<article class='manpage'>". implode(PHP_EOL, $lines2) ."</article>";
+ echo "<script src='/js/copy.js'></script>";
- $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 "<p class='hint'> Found $n result$s</p>";
-
- 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 "<p class='hint'> Found $n result$s</p>";
+
+ 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) ."&section=". urlencode($sect)
- ."&arch=". urlencode($arch) ."&action=man";
+ $url = "$root/search.php?query=". urlencode($name) ."&section=". urlencode($sect)
+ ."&arch=". urlencode($arch) ."&action=man";
- echo '<dl>';
- echo " <dt><a href='".$url."'>$fname($fsect)</a></dt>";
- echo " <dd>$desc</dd>";
- echo '</dl>';
+ echo '<dl>';
+ echo " <dt><a href='".$url."'>$fname($fsect)</a></dt>";
+ echo " <dd>$desc</dd>";
+ echo '</dl>';
+ }
}
+ else echo "<p class='hint'> No results.</p>";
}
- else echo "<p class='hint'> No results.</p>";
}
+ else echo "<p class='hint'> No input = no results.</p>";
?>
</section>
<footer>