Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions .github/workflows/fuzz.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
name: Fuzz Testing

on:
push:
branches: [master, main]
pull_request:
branches: [master, main]
schedule:
# Run weekly on Sunday at midnight
- cron: '0 0 * * 0'

jobs:
fuzz:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
fuzzer:
- pdf_parser
- pdf_modify
- pdf_form
- jpeg_embed
- png_embed
- stream_decode
- object_parser
- pdf_string
- xref_stream
- page_embed

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm install

- name: Install fuzzing dependencies
run: npm install --no-save @jazzer.js/core esbuild

- name: Build fuzzer
run: |
npx esbuild fuzz/${{ matrix.fuzzer }}.fuzz.ts \
--bundle \
--platform=node \
--target=node18 \
--outfile=fuzz/${{ matrix.fuzzer }}.fuzz.js \
--format=cjs

- name: Run fuzzer regression test
run: |
npx jazzer fuzz/${{ matrix.fuzzer }}.fuzz.js \
--mode regression \
--corpus fuzz/corpus/pdf_parser \
--timeout 30

- name: Run short fuzz session
run: |
timeout 60 npx jazzer fuzz/${{ matrix.fuzzer }}.fuzz.js \
--corpus fuzz/corpus/pdf_parser \
--max_total_time 30 \
|| true

coverage:
runs-on: ubuntu-latest
needs: fuzz
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm install

- name: Install fuzzing dependencies
run: npm install --no-save @jazzer.js/core esbuild

- name: Build all fuzzers
run: |
for fuzzer in pdf_parser pdf_modify pdf_form jpeg_embed png_embed stream_decode object_parser pdf_string xref_stream page_embed; do
npx esbuild fuzz/${fuzzer}.fuzz.ts --bundle --platform=node --target=node18 --outfile=fuzz/${fuzzer}.fuzz.js --format=cjs
done

- name: Generate combined coverage report
run: |
for fuzzer in pdf_parser pdf_modify pdf_form jpeg_embed png_embed stream_decode object_parser pdf_string xref_stream page_embed; do
echo "Running coverage for ${fuzzer}..."
npx jazzer fuzz/${fuzzer}.fuzz.js \
--corpus fuzz/corpus/pdf_parser \
--coverage \
--mode regression \
|| true
done

- name: Upload coverage
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
109 changes: 109 additions & 0 deletions fuzz/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# pdf-lib Fuzzing

This directory contains fuzz targets for [OSS-Fuzz](https://github.com/google/oss-fuzz) integration.

## Fuzz Targets

| Fuzzer | Target | Description |
|--------|--------|-------------|
| `pdf_parser` | PDF parsing | Main PDF document parsing via `PDFDocument.load()` |
| `pdf_modify` | PDF modification | Loading, modifying, and saving PDFs |
| `pdf_form` | Form parsing | AcroForm field parsing and manipulation |
| `jpeg_embed` | JPEG embedding | JPEG image parsing via `embedJpg()` |
| `png_embed` | PNG embedding | PNG image parsing via `embedPng()` |
| `stream_decode` | Stream decoders | FlateStream, LZWStream, Ascii85, AsciiHex, RunLength |
| `object_parser` | Object parsing | Individual PDF object parsing (dicts, arrays, strings) |
| `pdf_string` | String parsing | PDFString/PDFHexString escape sequences and encoding |
| `xref_stream` | XRef streams | Cross-reference stream parsing |
| `page_embed` | Page embedding | PDF page embedding and copying |

## Running Locally

### Prerequisites

```bash
npm install
npm install --no-save @jazzer.js/core esbuild
```

### Build a Fuzzer

```bash
npx esbuild fuzz/pdf_parser.fuzz.ts \
--bundle \
--platform=node \
--target=node18 \
--outfile=fuzz/pdf_parser.fuzz.js \
--format=cjs
```

### Run a Fuzzer

```bash
# Run with seed corpus
npx jazzer fuzz/pdf_parser.fuzz.js --corpus fuzz/corpus/pdf_parser

# Run for 60 seconds
npx jazzer fuzz/pdf_parser.fuzz.js --max_total_time 60

# Regression test (run corpus without fuzzing)
npx jazzer fuzz/pdf_parser.fuzz.js --mode regression --corpus fuzz/corpus/pdf_parser
```

## Directory Structure

```
fuzz/
├── *.fuzz.ts # Fuzz target source files
├── *.dict # Dictionaries (PDF, JPEG, PNG tokens)
├── *.options # Fuzzer options (timeouts, memory limits)
├── corpus/ # Seed corpora
│ ├── pdf_parser/ # PDF samples
│ ├── pdf_modify/ # PDF samples
│ ├── pdf_form/ # Form PDFs
│ ├── jpeg_embed/ # JPEG images
│ └── png_embed/ # PNG images
└── README.md # This file
```

## OSS-Fuzz Integration

The OSS-Fuzz configuration is in `oss-fuzz/` at the repository root:

- `Dockerfile` - Build environment
- `build.sh` - Build script
- `project.yaml` - Project metadata

## Adding New Fuzzers

1. Create `fuzz/new_fuzzer.fuzz.ts`:

```typescript
export async function fuzz(data: Buffer): Promise<void> {
if (data.length === 0 || data.length > MAX_SIZE) return;

try {
// Your fuzzing logic here
} catch (e) {
// Expected for malformed input
}
}
```

2. Add dictionary if needed: `fuzz/new_fuzzer.dict`
3. Add seed corpus: `fuzz/corpus/new_fuzzer/`
4. Add options file if needed: `fuzz/new_fuzzer.options`
5. Update `oss-fuzz/build.sh` to include the new fuzzer

## Coverage

To generate coverage reports:

```bash
npx jazzer fuzz/pdf_parser.fuzz.js \
--corpus fuzz/corpus/pdf_parser \
--coverage \
--mode regression
```

Reports are generated in `./coverage/`.
Binary file added fuzz/corpus/jpeg_embed/cat_riding_unicorn.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/jpeg_embed/cmyk_colorspace.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/jpeg_embed/minions_laughing.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/pdf_form/create_form.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_form/fill_form.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_form/flatten_form.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_form/form_to_flatten.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_form/sample_form.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/american_flag.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/bixby_guide.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/dod_character.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/encrypted_new.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/encrypted_old.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/fancy_fields.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/form_to_flatten.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/giraffe.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/invalid_root_ref.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/just_metadata.pdf
Binary file not shown.
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/missing_endobj_keyword.pdf
Binary file not shown.
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/normal.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/sample_form.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/simple.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/standard_fonts_demo.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/stream-writer-1.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/stuff_following_header.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/us_constitution.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/with_annots.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/with_combed_fields.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/with_comments.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/with_cropbox.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/with_invalid_objects.pdf
Binary file not shown.
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/with_large_page_count.pdf
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/with_signature.pdf
Binary file not shown.
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/with_viewer_prefs.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_modify/with_xfa_fields.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/american_flag.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/bad_header.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/bixby_guide.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/dod_character.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/empty_page.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/encrypted_new.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/encrypted_old.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/fancy_fields.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/form_to_flatten.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/giraffe.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/hex_string.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/invalid_root_ref.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/just_metadata.pdf
Binary file not shown.
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/literal_string.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/minimal.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/missing_endobj_keyword.pdf
Binary file not shown.
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/nested_array.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/no_xref.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/normal.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/sample_form.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/simple.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/standard_fonts_demo.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/stream-writer-1.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/stuff_following_header.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/truncated.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/us_constitution.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/with_annots.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/with_combed_fields.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/with_comments.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/with_cropbox.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/with_invalid_objects.pdf
Binary file not shown.
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/with_large_page_count.pdf
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/with_signature.pdf
Binary file not shown.
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/with_viewer_prefs.pdf
Binary file not shown.
Binary file added fuzz/corpus/pdf_parser/with_xfa_fields.pdf
Binary file not shown.
Binary file added fuzz/corpus/png_embed/PngSuite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basi0g01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basi0g02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basi0g04.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basi0g08.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basi0g16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basi2c08.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basi2c16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basi3p01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basi3p02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basi3p04.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basi3p08.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basi4a08.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basi4a16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basi6a08.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basi6a16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basn0g01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basn0g02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basn0g04.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basn0g08.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basn0g16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added fuzz/corpus/png_embed/basn2c08.png
Binary file added fuzz/corpus/png_embed/basn2c16.png
Binary file added fuzz/corpus/png_embed/basn3p01.png
Binary file added fuzz/corpus/png_embed/basn3p02.png
Binary file added fuzz/corpus/png_embed/basn3p04.png
Binary file added fuzz/corpus/png_embed/basn3p08.png
Binary file added fuzz/corpus/png_embed/basn4a08.png
Binary file added fuzz/corpus/png_embed/basn4a16.png
Binary file added fuzz/corpus/png_embed/basn6a08.png
Binary file added fuzz/corpus/png_embed/basn6a16.png
Binary file added fuzz/corpus/png_embed/bgai4a08.png
Binary file added fuzz/corpus/png_embed/bgai4a16.png
Binary file added fuzz/corpus/png_embed/bgan6a08.png
Binary file added fuzz/corpus/png_embed/bgan6a16.png
Binary file added fuzz/corpus/png_embed/bgbn4a08.png
Binary file added fuzz/corpus/png_embed/bggn4a16.png
Binary file added fuzz/corpus/png_embed/bgwn6a08.png
Binary file added fuzz/corpus/png_embed/bgyn6a16.png
Binary file added fuzz/corpus/png_embed/ccwn2c08.png
Binary file added fuzz/corpus/png_embed/ccwn3p08.png
Binary file added fuzz/corpus/png_embed/cdfn2c08.png
Binary file added fuzz/corpus/png_embed/cdhn2c08.png
Binary file added fuzz/corpus/png_embed/cdsn2c08.png
Binary file added fuzz/corpus/png_embed/cdun2c08.png
Binary file added fuzz/corpus/png_embed/ch1n3p04.png
Binary file added fuzz/corpus/png_embed/ch2n3p08.png
Binary file added fuzz/corpus/png_embed/cm0n0g04.png
Binary file added fuzz/corpus/png_embed/cm7n0g04.png
Binary file added fuzz/corpus/png_embed/cm9n0g04.png
Binary file added fuzz/corpus/png_embed/cs3n2c16.png
Binary file added fuzz/corpus/png_embed/cs3n3p08.png
Binary file added fuzz/corpus/png_embed/cs5n2c08.png
Binary file added fuzz/corpus/png_embed/cs5n3p08.png
Binary file added fuzz/corpus/png_embed/cs8n2c08.png
Binary file added fuzz/corpus/png_embed/cs8n3p08.png
Binary file added fuzz/corpus/png_embed/ct0n0g04.png
Binary file added fuzz/corpus/png_embed/ct1n0g04.png
Binary file added fuzz/corpus/png_embed/cten0g04.png
Binary file added fuzz/corpus/png_embed/ctfn0g04.png
Binary file added fuzz/corpus/png_embed/ctgn0g04.png
Binary file added fuzz/corpus/png_embed/cthn0g04.png
Binary file added fuzz/corpus/png_embed/ctjn0g04.png
Binary file added fuzz/corpus/png_embed/ctzn0g04.png
Binary file added fuzz/corpus/png_embed/etwe.png
Binary file added fuzz/corpus/png_embed/exif2c08.png
Binary file added fuzz/corpus/png_embed/f00n0g08.png
Binary file added fuzz/corpus/png_embed/f00n2c08.png
Binary file added fuzz/corpus/png_embed/f01n0g08.png
Binary file added fuzz/corpus/png_embed/f01n2c08.png
Binary file added fuzz/corpus/png_embed/f02n0g08.png
Binary file added fuzz/corpus/png_embed/f02n2c08.png
Binary file added fuzz/corpus/png_embed/f03n0g08.png
Binary file added fuzz/corpus/png_embed/f03n2c08.png
Binary file added fuzz/corpus/png_embed/f04n0g08.png
Binary file added fuzz/corpus/png_embed/f04n2c08.png
Binary file added fuzz/corpus/png_embed/f99n0g04.png
Binary file added fuzz/corpus/png_embed/g03n0g16.png
Binary file added fuzz/corpus/png_embed/g03n2c08.png
Binary file added fuzz/corpus/png_embed/g03n3p04.png
Binary file added fuzz/corpus/png_embed/g04n0g16.png
Binary file added fuzz/corpus/png_embed/g04n2c08.png
Binary file added fuzz/corpus/png_embed/g04n3p04.png
Binary file added fuzz/corpus/png_embed/g05n0g16.png
Binary file added fuzz/corpus/png_embed/g05n2c08.png
Binary file added fuzz/corpus/png_embed/g05n3p04.png
Binary file added fuzz/corpus/png_embed/g07n0g16.png
Binary file added fuzz/corpus/png_embed/g07n2c08.png
Binary file added fuzz/corpus/png_embed/g07n3p04.png
Binary file added fuzz/corpus/png_embed/g10n0g16.png
Binary file added fuzz/corpus/png_embed/g10n2c08.png
Binary file added fuzz/corpus/png_embed/g10n3p04.png
Binary file added fuzz/corpus/png_embed/g25n0g16.png
Binary file added fuzz/corpus/png_embed/g25n2c08.png
Binary file added fuzz/corpus/png_embed/g25n3p04.png
Binary file added fuzz/corpus/png_embed/greyscale_bird.png
Binary file added fuzz/corpus/png_embed/mario_emblem.png
Binary file added fuzz/corpus/png_embed/minions_banana_alpha.png
Binary file added fuzz/corpus/png_embed/oi1n0g16.png
Binary file added fuzz/corpus/png_embed/oi1n2c16.png
Binary file added fuzz/corpus/png_embed/oi2n0g16.png
Binary file added fuzz/corpus/png_embed/oi2n2c16.png
Binary file added fuzz/corpus/png_embed/oi4n0g16.png
Binary file added fuzz/corpus/png_embed/oi4n2c16.png
Binary file added fuzz/corpus/png_embed/oi9n0g16.png
Binary file added fuzz/corpus/png_embed/oi9n2c16.png
Binary file added fuzz/corpus/png_embed/pp0n2c16.png
Binary file added fuzz/corpus/png_embed/pp0n6a08.png
Binary file added fuzz/corpus/png_embed/ps1n0g08.png
Binary file added fuzz/corpus/png_embed/ps1n2c16.png
Binary file added fuzz/corpus/png_embed/ps2n0g08.png
Binary file added fuzz/corpus/png_embed/ps2n2c16.png
Binary file added fuzz/corpus/png_embed/s01i3p01.png
Binary file added fuzz/corpus/png_embed/s01n3p01.png
Binary file added fuzz/corpus/png_embed/s02i3p01.png
Binary file added fuzz/corpus/png_embed/s02n3p01.png
Binary file added fuzz/corpus/png_embed/s03i3p01.png
Binary file added fuzz/corpus/png_embed/s03n3p01.png
Binary file added fuzz/corpus/png_embed/s04i3p01.png
Binary file added fuzz/corpus/png_embed/s04n3p01.png
Binary file added fuzz/corpus/png_embed/s05i3p02.png
Binary file added fuzz/corpus/png_embed/s05n3p02.png
Binary file added fuzz/corpus/png_embed/s06i3p02.png
Binary file added fuzz/corpus/png_embed/s06n3p02.png
Binary file added fuzz/corpus/png_embed/s07i3p02.png
Binary file added fuzz/corpus/png_embed/s07n3p02.png
Binary file added fuzz/corpus/png_embed/s08i3p02.png
Binary file added fuzz/corpus/png_embed/s08n3p02.png
Binary file added fuzz/corpus/png_embed/s09i3p02.png
Binary file added fuzz/corpus/png_embed/s09n3p02.png
Binary file added fuzz/corpus/png_embed/s32i3p04.png
Binary file added fuzz/corpus/png_embed/s32n3p04.png
Binary file added fuzz/corpus/png_embed/s33i3p04.png
Binary file added fuzz/corpus/png_embed/s33n3p04.png
Binary file added fuzz/corpus/png_embed/s34i3p04.png
Binary file added fuzz/corpus/png_embed/s34n3p04.png
Binary file added fuzz/corpus/png_embed/s35i3p04.png
Binary file added fuzz/corpus/png_embed/s35n3p04.png
Binary file added fuzz/corpus/png_embed/s36i3p04.png
Binary file added fuzz/corpus/png_embed/s36n3p04.png
Binary file added fuzz/corpus/png_embed/s37i3p04.png
Binary file added fuzz/corpus/png_embed/s37n3p04.png
Binary file added fuzz/corpus/png_embed/s38i3p04.png
Binary file added fuzz/corpus/png_embed/s38n3p04.png
Binary file added fuzz/corpus/png_embed/s39i3p04.png
Binary file added fuzz/corpus/png_embed/s39n3p04.png
Binary file added fuzz/corpus/png_embed/s40i3p04.png
Binary file added fuzz/corpus/png_embed/s40n3p04.png
Binary file added fuzz/corpus/png_embed/self_drive.png
Binary file added fuzz/corpus/png_embed/small_mario.png
Binary file added fuzz/corpus/png_embed/small_mario_resized.png
Binary file added fuzz/corpus/png_embed/tbbn0g04.png
Binary file added fuzz/corpus/png_embed/tbbn2c16.png
Binary file added fuzz/corpus/png_embed/tbbn3p08.png
Binary file added fuzz/corpus/png_embed/tbgn2c16.png
Binary file added fuzz/corpus/png_embed/tbgn3p08.png
Binary file added fuzz/corpus/png_embed/tbrn2c08.png
Binary file added fuzz/corpus/png_embed/tbwn0g16.png
Binary file added fuzz/corpus/png_embed/tbwn3p08.png
Binary file added fuzz/corpus/png_embed/tbyn3p08.png
Binary file added fuzz/corpus/png_embed/tm3n3p02.png
Binary file added fuzz/corpus/png_embed/tp0n0g08.png
Binary file added fuzz/corpus/png_embed/tp0n2c08.png
Binary file added fuzz/corpus/png_embed/tp0n3p08.png
Binary file added fuzz/corpus/png_embed/tp1n3p08.png
Binary file added fuzz/corpus/png_embed/z00n2c08.png
Binary file added fuzz/corpus/png_embed/z03n2c08.png
Binary file added fuzz/corpus/png_embed/z06n2c08.png
Binary file added fuzz/corpus/png_embed/z09n2c08.png
1 change: 1 addition & 0 deletions fuzz/corpus/stream_decode/ascii85_test.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Gb"0E\!
1 change: 1 addition & 0 deletions fuzz/corpus/stream_decode/asciihex_hello.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
48656C6C6F>
Binary file added fuzz/corpus/stream_decode/flate_foo.bin
Binary file not shown.
1 change: 1 addition & 0 deletions fuzz/corpus/stream_decode/lzw_minimal.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
�����
1 change: 1 addition & 0 deletions fuzz/corpus/stream_decode/runlength_test.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello
72 changes: 72 additions & 0 deletions fuzz/jpeg.dict
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# JPEG dictionary for fuzzing
# JPEG markers (using hex)
"\xff\xd8"
"\xff\xd9"
"\xff\xe0"
"\xff\xe1"
"\xff\xdb"
"\xff\xc0"
"\xff\xc2"
"\xff\xc4"
"\xff\xda"
"\xff\xdd"
"\xff\xfe"

# JFIF header
"JFIF\x00"

# EXIF header
"Exif\x00\x00"

# APP segments
"\xff\xe0\x00\x10"
"\xff\xe1\x00\x08"

# Common segment lengths
"\x00\x02"
"\x00\x04"
"\x00\x08"
"\x00\x10"
"\x00\x40"
"\x00\x80"

# SOF markers
"\xff\xc0"
"\xff\xc1"
"\xff\xc2"
"\xff\xc3"

# Huffman table marker
"\xff\xc4"

# Quantization table marker
"\xff\xdb"

# SOS marker
"\xff\xda"

# RST markers
"\xff\xd0"
"\xff\xd1"
"\xff\xd2"
"\xff\xd3"
"\xff\xd4"
"\xff\xd5"
"\xff\xd6"
"\xff\xd7"

# Common dimensions
"\x00\x01"
"\x00\x64"
"\x01\x00"
"\x02\x00"
"\x04\x00"

# Bits per sample
"\x08"
"\x0c"

# Number of components
"\x01"
"\x03"
"\x04"
45 changes: 45 additions & 0 deletions fuzz/jpeg_embed.fuzz.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import PDFDocument from '../src/api/PDFDocument';

export async function fuzz(data: Buffer): Promise<void> {
// Skip empty or too large inputs
if (data.length === 0 || data.length > 512 * 1024) {
return;
}

try {
const pdfDoc = await PDFDocument.create();
const jpgImage = await pdfDoc.embedJpg(data);

// Exercise the embedded image
jpgImage.width;
jpgImage.height;
jpgImage.scale(0.5);
jpgImage.scaleToFit(100, 100);

// Draw the image on a page
const page = pdfDoc.addPage();
page.drawImage(jpgImage, {
x: 0,
y: 0,
width: Math.min(jpgImage.width, 100),
height: Math.min(jpgImage.height, 100),
});

} catch (e) {
// Expected for malformed JPEG data
}
}
3 changes: 3 additions & 0 deletions fuzz/jpeg_embed.options
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[libfuzzer]
max_len = 524288
timeout = 30
49 changes: 49 additions & 0 deletions fuzz/object_parser.fuzz.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
* Fuzzer for PDFObjectParser - parses individual PDF objects directly.
* Targets: hex strings, literal strings, arrays, dictionaries, streams, numbers, names.
*
* This fuzzer directly targets the low-level parser for maximum efficiency,
* avoiding the overhead of building and parsing full PDF documents.
*/

import PDFObjectParser from '../src/core/parser/PDFObjectParser';
import PDFContext from '../src/core/PDFContext';

export async function fuzz(data: Buffer): Promise<void> {
// Skip empty or too large inputs
// Using 256KB limit matching options file
if (data.length === 0 || data.length > 256 * 1024) {
return;
}

try {
const context = PDFContext.create();

// Parse directly using PDFObjectParser - no PDF wrapper needed
const parser = PDFObjectParser.forBytes(
new Uint8Array(data),
context,
false // capNumbers
);

// Try to parse an object from the fuzz data
parser.parseObject();

} catch (e) {
// Expected for malformed object data
}
}
Loading