Files
pdf/engine/fuzz/README.md
T

2.5 KiB

Fuzzing the PDF engine

fuzz_load.cpp is a libFuzzer harness that drives the full load → metadata → outline → render → text → annotations → hit-test → select path with arbitrary bytes. Combined with AddressSanitizer it surfaces crashes, OOMs, and undefined behaviour in the parsing and rendering code.

Resource ceilings from pdfengine/hardened_limits.h keep the fuzzer focused on logic bugs instead of trivial out-of-memory inputs (and those same ceilings now guard the production render path against integer-overflow / OOM).

Linux (primary)

Clang + libFuzzer + ASan is best supported on Linux. PDFium must be built with the same Clang toolchain (so ASan is consistent across the static lib).

# Full ASan + coverage fuzzer
cmake --preset fuzz-linux
cmake --build --preset fuzz-linux

# If your PDFium static lib is NOT ASan-instrumented, use coverage-only:
cmake --preset fuzz-linux-nosan
cmake --build --preset fuzz-linux-nosan

# Run it against the downloaded corpus as a seed set
python scripts/fetch_corpus.py                  # populates corpus/fuzz/ (gitignored)
mkdir -p engine/fuzz/artifacts
./out/build/fuzz-linux/bin/pdfengine_fuzz \
    -artifact_prefix=engine/fuzz/artifacts/ \
    corpus/fuzz/ corpus/

corpus/fuzz/ and corpus/ are passed as seed corpora; new coverage-expanding inputs are written back into the first directory. Crashes land in engine/fuzz/artifacts/ (gitignored).

Windows (clang-cl)

Native Windows fuzzing needs a Clang toolchain and a PDFium static lib built with the matching runtime. Configure with clang-cl and the existing x64-windows-static triplet, then enable fuzzing:

cmake -S . -B C:/Users/<you>/pdfeng-build/fuzz-win -G Ninja `
  -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl `
  -DVCPKG_TARGET_TRIPLET=x64-windows-static `
  -DPDFENGINE_FUZZING=ON -DPDFENGINE_WITH_PDFIUM=ON `
  -DPDFENGINE_FUZZ_SANITIZERS=fuzzer `
  --toolchain "$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake"
cmake --build C:/Users/<you>/pdfeng-build/fuzz-win

Use PDFENGINE_FUZZ_SANITIZERS=fuzzer (coverage-only) on Windows unless the whole dependency chain — including PDFium — is ASan-built, since mixing an ASan binary with a non-ASan MSVC static lib does not link cleanly.

Reproducing a crash

./pdfengine_fuzz engine/fuzz/artifacts/crash-<hash>

The ASan report points at the offending allocation/access; the input file is the minimal reproducer (run with -minimize_crash=1 to shrink further).