harden(make-pdf): emoji gate + font install per adversarial review

Codex adversarial pass on the implementation diff flagged five robustness
gaps, all fixed here:
- emoji-gate skipped green in CI when poppler/font prerequisites were absent,
  which could let the tofu regression ship behind a green build. Missing
  prerequisites are now a HARD FAILURE when process.env.CI is set; local dev
  still skips cleanly.
- execFileSync children (make-pdf, pdffonts, pdftoppm, fc-match) had no
  timeout; a wedged binary or hostile GSTACK_*_BIN override could hang the
  job past Bun's test timeout. Each child now has a 25s ceiling.
- PPM parser trusted header tokens blindly; malformed/variant output gave a
  silently-wrong count. Now validates magic/dimensions/maxval and pixel-buffer
  length, handles header comments, throws a hard diagnostic on mismatch.
- predictable /tmp paths were collision/symlink-prone; now mkdtempSync under
  /tmp (kept under /tmp for browse's validateOutputPath allowlist).
- only apt-get update was timeout-wrapped; dnf/pacman/apk installs and apt
  install can hang on locks/mirrors. All package installs now timeout-bound.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-05-29 07:14:52 -07:00
parent 2aa7b9c4ff
commit 13e0f9b4c8
3 changed files with 70 additions and 19 deletions
+6 -4
View File
@@ -296,19 +296,21 @@ ensure_emoji_font() {
sudo="sudo -n"
fi
# Every package-manager call is wrapped in `timeout` so a stuck dpkg/rpm lock
# or a wedged mirror fails fast into the warn path instead of hanging setup.
if command -v apt-get >/dev/null 2>&1; then
echo "Installing color-emoji font (fonts-noto-color-emoji) so make-pdf emoji render (set GSTACK_SKIP_FONTS=1 to skip)..."
DEBIAN_FRONTEND=noninteractive timeout 30 $sudo apt-get update -qq >/dev/null 2>&1 || true
DEBIAN_FRONTEND=noninteractive $sudo apt-get install -y -qq fonts-noto-color-emoji >/dev/null 2>&1 || return 1
DEBIAN_FRONTEND=noninteractive timeout 120 $sudo apt-get install -y -qq fonts-noto-color-emoji >/dev/null 2>&1 || return 1
elif command -v dnf >/dev/null 2>&1; then
echo "Installing color-emoji font (google-noto-color-emoji-fonts)..."
$sudo dnf install -y google-noto-color-emoji-fonts >/dev/null 2>&1 || return 1
timeout 120 $sudo dnf install -y google-noto-color-emoji-fonts >/dev/null 2>&1 || return 1
elif command -v pacman >/dev/null 2>&1; then
echo "Installing color-emoji font (noto-fonts-emoji)..."
$sudo pacman -Sy --noconfirm noto-fonts-emoji >/dev/null 2>&1 || return 1
timeout 120 $sudo pacman -Sy --noconfirm noto-fonts-emoji >/dev/null 2>&1 || return 1
elif command -v apk >/dev/null 2>&1; then
echo "Installing color-emoji font (font-noto-emoji)..."
$sudo apk add --no-cache font-noto-emoji >/dev/null 2>&1 || return 1
timeout 120 $sudo apk add --no-cache font-noto-emoji >/dev/null 2>&1 || return 1
else
return 1
fi