diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml new file mode 100644 index 000000000..460684c6a --- /dev/null +++ b/.github/workflows/fuzz.yml @@ -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/ diff --git a/fuzz/README.md b/fuzz/README.md new file mode 100644 index 000000000..6496ce041 --- /dev/null +++ b/fuzz/README.md @@ -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 { + 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/`. diff --git a/fuzz/corpus/jpeg_embed/cat_riding_unicorn.jpg b/fuzz/corpus/jpeg_embed/cat_riding_unicorn.jpg new file mode 100644 index 000000000..bae32ce4e Binary files /dev/null and b/fuzz/corpus/jpeg_embed/cat_riding_unicorn.jpg differ diff --git a/fuzz/corpus/jpeg_embed/cat_riding_unicorn_resized.jpg b/fuzz/corpus/jpeg_embed/cat_riding_unicorn_resized.jpg new file mode 100644 index 000000000..23f880446 Binary files /dev/null and b/fuzz/corpus/jpeg_embed/cat_riding_unicorn_resized.jpg differ diff --git a/fuzz/corpus/jpeg_embed/cmyk_colorspace.jpg b/fuzz/corpus/jpeg_embed/cmyk_colorspace.jpg new file mode 100644 index 000000000..a489c0dfd Binary files /dev/null and b/fuzz/corpus/jpeg_embed/cmyk_colorspace.jpg differ diff --git a/fuzz/corpus/jpeg_embed/minions_laughing.jpg b/fuzz/corpus/jpeg_embed/minions_laughing.jpg new file mode 100644 index 000000000..2468eaece Binary files /dev/null and b/fuzz/corpus/jpeg_embed/minions_laughing.jpg differ diff --git a/fuzz/corpus/pdf_form/create_form.pdf b/fuzz/corpus/pdf_form/create_form.pdf new file mode 100644 index 000000000..75ac0d1a4 Binary files /dev/null and b/fuzz/corpus/pdf_form/create_form.pdf differ diff --git a/fuzz/corpus/pdf_form/fill_form.pdf b/fuzz/corpus/pdf_form/fill_form.pdf new file mode 100644 index 000000000..73589c1e2 Binary files /dev/null and b/fuzz/corpus/pdf_form/fill_form.pdf differ diff --git a/fuzz/corpus/pdf_form/flatten_form.pdf b/fuzz/corpus/pdf_form/flatten_form.pdf new file mode 100644 index 000000000..aaeaca773 Binary files /dev/null and b/fuzz/corpus/pdf_form/flatten_form.pdf differ diff --git a/fuzz/corpus/pdf_form/form_to_flatten.pdf b/fuzz/corpus/pdf_form/form_to_flatten.pdf new file mode 100644 index 000000000..322144190 Binary files /dev/null and b/fuzz/corpus/pdf_form/form_to_flatten.pdf differ diff --git a/fuzz/corpus/pdf_form/sample_form.pdf b/fuzz/corpus/pdf_form/sample_form.pdf new file mode 100644 index 000000000..c3c38bc64 Binary files /dev/null and b/fuzz/corpus/pdf_form/sample_form.pdf differ diff --git a/fuzz/corpus/pdf_modify/american_flag.pdf b/fuzz/corpus/pdf_modify/american_flag.pdf new file mode 100644 index 000000000..a8cc77f89 Binary files /dev/null and b/fuzz/corpus/pdf_modify/american_flag.pdf differ diff --git a/fuzz/corpus/pdf_modify/bixby_guide.pdf b/fuzz/corpus/pdf_modify/bixby_guide.pdf new file mode 100644 index 000000000..f8fb8ea9a Binary files /dev/null and b/fuzz/corpus/pdf_modify/bixby_guide.pdf differ diff --git a/fuzz/corpus/pdf_modify/dod_character.pdf b/fuzz/corpus/pdf_modify/dod_character.pdf new file mode 100644 index 000000000..f5701d609 Binary files /dev/null and b/fuzz/corpus/pdf_modify/dod_character.pdf differ diff --git a/fuzz/corpus/pdf_modify/encrypted_new.pdf b/fuzz/corpus/pdf_modify/encrypted_new.pdf new file mode 100644 index 000000000..898a28ee9 Binary files /dev/null and b/fuzz/corpus/pdf_modify/encrypted_new.pdf differ diff --git a/fuzz/corpus/pdf_modify/encrypted_old.pdf b/fuzz/corpus/pdf_modify/encrypted_old.pdf new file mode 100644 index 000000000..92b8bb364 Binary files /dev/null and b/fuzz/corpus/pdf_modify/encrypted_old.pdf differ diff --git a/fuzz/corpus/pdf_modify/fancy_fields.pdf b/fuzz/corpus/pdf_modify/fancy_fields.pdf new file mode 100644 index 000000000..0d14264df Binary files /dev/null and b/fuzz/corpus/pdf_modify/fancy_fields.pdf differ diff --git a/fuzz/corpus/pdf_modify/form_to_flatten.pdf b/fuzz/corpus/pdf_modify/form_to_flatten.pdf new file mode 100644 index 000000000..322144190 Binary files /dev/null and b/fuzz/corpus/pdf_modify/form_to_flatten.pdf differ diff --git a/fuzz/corpus/pdf_modify/giraffe.pdf b/fuzz/corpus/pdf_modify/giraffe.pdf new file mode 100644 index 000000000..bdba0a6b3 Binary files /dev/null and b/fuzz/corpus/pdf_modify/giraffe.pdf differ diff --git a/fuzz/corpus/pdf_modify/invalid_root_ref.pdf b/fuzz/corpus/pdf_modify/invalid_root_ref.pdf new file mode 100644 index 000000000..c52cde328 Binary files /dev/null and b/fuzz/corpus/pdf_modify/invalid_root_ref.pdf differ diff --git a/fuzz/corpus/pdf_modify/just_metadata.pdf b/fuzz/corpus/pdf_modify/just_metadata.pdf new file mode 100644 index 000000000..6399cb5c7 Binary files /dev/null and b/fuzz/corpus/pdf_modify/just_metadata.pdf differ diff --git a/fuzz/corpus/pdf_modify/linearized_with_object_streams.pdf b/fuzz/corpus/pdf_modify/linearized_with_object_streams.pdf new file mode 100755 index 000000000..9dec084d2 Binary files /dev/null and b/fuzz/corpus/pdf_modify/linearized_with_object_streams.pdf differ diff --git a/fuzz/corpus/pdf_modify/missing_endobj_keyword.pdf b/fuzz/corpus/pdf_modify/missing_endobj_keyword.pdf new file mode 100644 index 000000000..09b2655d8 Binary files /dev/null and b/fuzz/corpus/pdf_modify/missing_endobj_keyword.pdf differ diff --git a/fuzz/corpus/pdf_modify/missing_xref_trailer_dict.pdf b/fuzz/corpus/pdf_modify/missing_xref_trailer_dict.pdf new file mode 100644 index 000000000..7a3deab09 Binary files /dev/null and b/fuzz/corpus/pdf_modify/missing_xref_trailer_dict.pdf differ diff --git a/fuzz/corpus/pdf_modify/normal.pdf b/fuzz/corpus/pdf_modify/normal.pdf new file mode 100644 index 000000000..5a0b50637 Binary files /dev/null and b/fuzz/corpus/pdf_modify/normal.pdf differ diff --git a/fuzz/corpus/pdf_modify/sample_form.pdf b/fuzz/corpus/pdf_modify/sample_form.pdf new file mode 100644 index 000000000..c3c38bc64 Binary files /dev/null and b/fuzz/corpus/pdf_modify/sample_form.pdf differ diff --git a/fuzz/corpus/pdf_modify/simple.pdf b/fuzz/corpus/pdf_modify/simple.pdf new file mode 100644 index 000000000..65e6bcf22 Binary files /dev/null and b/fuzz/corpus/pdf_modify/simple.pdf differ diff --git a/fuzz/corpus/pdf_modify/standard_fonts_demo.pdf b/fuzz/corpus/pdf_modify/standard_fonts_demo.pdf new file mode 100644 index 000000000..64ec06b55 Binary files /dev/null and b/fuzz/corpus/pdf_modify/standard_fonts_demo.pdf differ diff --git a/fuzz/corpus/pdf_modify/stream-writer-1.pdf b/fuzz/corpus/pdf_modify/stream-writer-1.pdf new file mode 100644 index 000000000..88ea972d7 Binary files /dev/null and b/fuzz/corpus/pdf_modify/stream-writer-1.pdf differ diff --git a/fuzz/corpus/pdf_modify/stuff_following_header.pdf b/fuzz/corpus/pdf_modify/stuff_following_header.pdf new file mode 100644 index 000000000..ab88eff79 Binary files /dev/null and b/fuzz/corpus/pdf_modify/stuff_following_header.pdf differ diff --git a/fuzz/corpus/pdf_modify/us_constitution.pdf b/fuzz/corpus/pdf_modify/us_constitution.pdf new file mode 100644 index 000000000..3402e2c32 Binary files /dev/null and b/fuzz/corpus/pdf_modify/us_constitution.pdf differ diff --git a/fuzz/corpus/pdf_modify/with_annots.pdf b/fuzz/corpus/pdf_modify/with_annots.pdf new file mode 100644 index 000000000..4682bf0c6 Binary files /dev/null and b/fuzz/corpus/pdf_modify/with_annots.pdf differ diff --git a/fuzz/corpus/pdf_modify/with_combed_fields.pdf b/fuzz/corpus/pdf_modify/with_combed_fields.pdf new file mode 100644 index 000000000..6fd151ca3 Binary files /dev/null and b/fuzz/corpus/pdf_modify/with_combed_fields.pdf differ diff --git a/fuzz/corpus/pdf_modify/with_comments.pdf b/fuzz/corpus/pdf_modify/with_comments.pdf new file mode 100644 index 000000000..ec99b75dc Binary files /dev/null and b/fuzz/corpus/pdf_modify/with_comments.pdf differ diff --git a/fuzz/corpus/pdf_modify/with_cropbox.pdf b/fuzz/corpus/pdf_modify/with_cropbox.pdf new file mode 100644 index 000000000..cf3bf9a0c Binary files /dev/null and b/fuzz/corpus/pdf_modify/with_cropbox.pdf differ diff --git a/fuzz/corpus/pdf_modify/with_invalid_objects.pdf b/fuzz/corpus/pdf_modify/with_invalid_objects.pdf new file mode 100644 index 000000000..3633b61a3 Binary files /dev/null and b/fuzz/corpus/pdf_modify/with_invalid_objects.pdf differ diff --git a/fuzz/corpus/pdf_modify/with_invalid_stream_EOL.pdf b/fuzz/corpus/pdf_modify/with_invalid_stream_EOL.pdf new file mode 100644 index 000000000..09583400d Binary files /dev/null and b/fuzz/corpus/pdf_modify/with_invalid_stream_EOL.pdf differ diff --git a/fuzz/corpus/pdf_modify/with_large_page_count.pdf b/fuzz/corpus/pdf_modify/with_large_page_count.pdf new file mode 100644 index 000000000..9899c5829 Binary files /dev/null and b/fuzz/corpus/pdf_modify/with_large_page_count.pdf differ diff --git a/fuzz/corpus/pdf_modify/with_missing_endstream_eol_and_polluted_ctm.pdf b/fuzz/corpus/pdf_modify/with_missing_endstream_eol_and_polluted_ctm.pdf new file mode 100644 index 000000000..6eb0d82c5 Binary files /dev/null and b/fuzz/corpus/pdf_modify/with_missing_endstream_eol_and_polluted_ctm.pdf differ diff --git a/fuzz/corpus/pdf_modify/with_newline_whitespace_in_indirect_object_numbers.pdf b/fuzz/corpus/pdf_modify/with_newline_whitespace_in_indirect_object_numbers.pdf new file mode 100644 index 000000000..93fe72c89 Binary files /dev/null and b/fuzz/corpus/pdf_modify/with_newline_whitespace_in_indirect_object_numbers.pdf differ diff --git a/fuzz/corpus/pdf_modify/with_null_parent_entry.pdf b/fuzz/corpus/pdf_modify/with_null_parent_entry.pdf new file mode 100644 index 000000000..fdcf323c2 Binary files /dev/null and b/fuzz/corpus/pdf_modify/with_null_parent_entry.pdf differ diff --git a/fuzz/corpus/pdf_modify/with_rotated_image_button.pdf b/fuzz/corpus/pdf_modify/with_rotated_image_button.pdf new file mode 100644 index 000000000..76f9a7d28 Binary files /dev/null and b/fuzz/corpus/pdf_modify/with_rotated_image_button.pdf differ diff --git a/fuzz/corpus/pdf_modify/with_signature.pdf b/fuzz/corpus/pdf_modify/with_signature.pdf new file mode 100644 index 000000000..193a2b68d Binary files /dev/null and b/fuzz/corpus/pdf_modify/with_signature.pdf differ diff --git a/fuzz/corpus/pdf_modify/with_update_sections.pdf b/fuzz/corpus/pdf_modify/with_update_sections.pdf new file mode 100644 index 000000000..dd1cb1d23 Binary files /dev/null and b/fuzz/corpus/pdf_modify/with_update_sections.pdf differ diff --git a/fuzz/corpus/pdf_modify/with_viewer_prefs.pdf b/fuzz/corpus/pdf_modify/with_viewer_prefs.pdf new file mode 100644 index 000000000..97cd33c13 Binary files /dev/null and b/fuzz/corpus/pdf_modify/with_viewer_prefs.pdf differ diff --git a/fuzz/corpus/pdf_modify/with_xfa_fields.pdf b/fuzz/corpus/pdf_modify/with_xfa_fields.pdf new file mode 100644 index 000000000..e19c72eca Binary files /dev/null and b/fuzz/corpus/pdf_modify/with_xfa_fields.pdf differ diff --git a/fuzz/corpus/pdf_parser/american_flag.pdf b/fuzz/corpus/pdf_parser/american_flag.pdf new file mode 100644 index 000000000..a8cc77f89 Binary files /dev/null and b/fuzz/corpus/pdf_parser/american_flag.pdf differ diff --git a/fuzz/corpus/pdf_parser/bad_header.pdf b/fuzz/corpus/pdf_parser/bad_header.pdf new file mode 100644 index 000000000..227ef2a9f Binary files /dev/null and b/fuzz/corpus/pdf_parser/bad_header.pdf differ diff --git a/fuzz/corpus/pdf_parser/bixby_guide.pdf b/fuzz/corpus/pdf_parser/bixby_guide.pdf new file mode 100644 index 000000000..f8fb8ea9a Binary files /dev/null and b/fuzz/corpus/pdf_parser/bixby_guide.pdf differ diff --git a/fuzz/corpus/pdf_parser/dod_character.pdf b/fuzz/corpus/pdf_parser/dod_character.pdf new file mode 100644 index 000000000..f5701d609 Binary files /dev/null and b/fuzz/corpus/pdf_parser/dod_character.pdf differ diff --git a/fuzz/corpus/pdf_parser/empty_page.pdf b/fuzz/corpus/pdf_parser/empty_page.pdf new file mode 100644 index 000000000..e1aa0bbb7 Binary files /dev/null and b/fuzz/corpus/pdf_parser/empty_page.pdf differ diff --git a/fuzz/corpus/pdf_parser/encrypted_new.pdf b/fuzz/corpus/pdf_parser/encrypted_new.pdf new file mode 100644 index 000000000..898a28ee9 Binary files /dev/null and b/fuzz/corpus/pdf_parser/encrypted_new.pdf differ diff --git a/fuzz/corpus/pdf_parser/encrypted_old.pdf b/fuzz/corpus/pdf_parser/encrypted_old.pdf new file mode 100644 index 000000000..92b8bb364 Binary files /dev/null and b/fuzz/corpus/pdf_parser/encrypted_old.pdf differ diff --git a/fuzz/corpus/pdf_parser/fancy_fields.pdf b/fuzz/corpus/pdf_parser/fancy_fields.pdf new file mode 100644 index 000000000..0d14264df Binary files /dev/null and b/fuzz/corpus/pdf_parser/fancy_fields.pdf differ diff --git a/fuzz/corpus/pdf_parser/form_to_flatten.pdf b/fuzz/corpus/pdf_parser/form_to_flatten.pdf new file mode 100644 index 000000000..322144190 Binary files /dev/null and b/fuzz/corpus/pdf_parser/form_to_flatten.pdf differ diff --git a/fuzz/corpus/pdf_parser/giraffe.pdf b/fuzz/corpus/pdf_parser/giraffe.pdf new file mode 100644 index 000000000..bdba0a6b3 Binary files /dev/null and b/fuzz/corpus/pdf_parser/giraffe.pdf differ diff --git a/fuzz/corpus/pdf_parser/hex_string.pdf b/fuzz/corpus/pdf_parser/hex_string.pdf new file mode 100644 index 000000000..f86fa76c0 Binary files /dev/null and b/fuzz/corpus/pdf_parser/hex_string.pdf differ diff --git a/fuzz/corpus/pdf_parser/invalid_root_ref.pdf b/fuzz/corpus/pdf_parser/invalid_root_ref.pdf new file mode 100644 index 000000000..c52cde328 Binary files /dev/null and b/fuzz/corpus/pdf_parser/invalid_root_ref.pdf differ diff --git a/fuzz/corpus/pdf_parser/just_metadata.pdf b/fuzz/corpus/pdf_parser/just_metadata.pdf new file mode 100644 index 000000000..6399cb5c7 Binary files /dev/null and b/fuzz/corpus/pdf_parser/just_metadata.pdf differ diff --git a/fuzz/corpus/pdf_parser/linearized_with_object_streams.pdf b/fuzz/corpus/pdf_parser/linearized_with_object_streams.pdf new file mode 100755 index 000000000..9dec084d2 Binary files /dev/null and b/fuzz/corpus/pdf_parser/linearized_with_object_streams.pdf differ diff --git a/fuzz/corpus/pdf_parser/literal_string.pdf b/fuzz/corpus/pdf_parser/literal_string.pdf new file mode 100644 index 000000000..3fe7697a5 Binary files /dev/null and b/fuzz/corpus/pdf_parser/literal_string.pdf differ diff --git a/fuzz/corpus/pdf_parser/minimal.pdf b/fuzz/corpus/pdf_parser/minimal.pdf new file mode 100644 index 000000000..c88fc103a Binary files /dev/null and b/fuzz/corpus/pdf_parser/minimal.pdf differ diff --git a/fuzz/corpus/pdf_parser/missing_endobj_keyword.pdf b/fuzz/corpus/pdf_parser/missing_endobj_keyword.pdf new file mode 100644 index 000000000..09b2655d8 Binary files /dev/null and b/fuzz/corpus/pdf_parser/missing_endobj_keyword.pdf differ diff --git a/fuzz/corpus/pdf_parser/missing_xref_trailer_dict.pdf b/fuzz/corpus/pdf_parser/missing_xref_trailer_dict.pdf new file mode 100644 index 000000000..7a3deab09 Binary files /dev/null and b/fuzz/corpus/pdf_parser/missing_xref_trailer_dict.pdf differ diff --git a/fuzz/corpus/pdf_parser/nested_array.pdf b/fuzz/corpus/pdf_parser/nested_array.pdf new file mode 100644 index 000000000..20ff2c5a6 Binary files /dev/null and b/fuzz/corpus/pdf_parser/nested_array.pdf differ diff --git a/fuzz/corpus/pdf_parser/no_xref.pdf b/fuzz/corpus/pdf_parser/no_xref.pdf new file mode 100644 index 000000000..da37ba0b4 Binary files /dev/null and b/fuzz/corpus/pdf_parser/no_xref.pdf differ diff --git a/fuzz/corpus/pdf_parser/normal.pdf b/fuzz/corpus/pdf_parser/normal.pdf new file mode 100644 index 000000000..5a0b50637 Binary files /dev/null and b/fuzz/corpus/pdf_parser/normal.pdf differ diff --git a/fuzz/corpus/pdf_parser/sample_form.pdf b/fuzz/corpus/pdf_parser/sample_form.pdf new file mode 100644 index 000000000..c3c38bc64 Binary files /dev/null and b/fuzz/corpus/pdf_parser/sample_form.pdf differ diff --git a/fuzz/corpus/pdf_parser/simple.pdf b/fuzz/corpus/pdf_parser/simple.pdf new file mode 100644 index 000000000..65e6bcf22 Binary files /dev/null and b/fuzz/corpus/pdf_parser/simple.pdf differ diff --git a/fuzz/corpus/pdf_parser/standard_fonts_demo.pdf b/fuzz/corpus/pdf_parser/standard_fonts_demo.pdf new file mode 100644 index 000000000..64ec06b55 Binary files /dev/null and b/fuzz/corpus/pdf_parser/standard_fonts_demo.pdf differ diff --git a/fuzz/corpus/pdf_parser/stream-writer-1.pdf b/fuzz/corpus/pdf_parser/stream-writer-1.pdf new file mode 100644 index 000000000..88ea972d7 Binary files /dev/null and b/fuzz/corpus/pdf_parser/stream-writer-1.pdf differ diff --git a/fuzz/corpus/pdf_parser/stuff_following_header.pdf b/fuzz/corpus/pdf_parser/stuff_following_header.pdf new file mode 100644 index 000000000..ab88eff79 Binary files /dev/null and b/fuzz/corpus/pdf_parser/stuff_following_header.pdf differ diff --git a/fuzz/corpus/pdf_parser/truncated.pdf b/fuzz/corpus/pdf_parser/truncated.pdf new file mode 100644 index 000000000..516849cbe Binary files /dev/null and b/fuzz/corpus/pdf_parser/truncated.pdf differ diff --git a/fuzz/corpus/pdf_parser/us_constitution.pdf b/fuzz/corpus/pdf_parser/us_constitution.pdf new file mode 100644 index 000000000..3402e2c32 Binary files /dev/null and b/fuzz/corpus/pdf_parser/us_constitution.pdf differ diff --git a/fuzz/corpus/pdf_parser/with_annots.pdf b/fuzz/corpus/pdf_parser/with_annots.pdf new file mode 100644 index 000000000..4682bf0c6 Binary files /dev/null and b/fuzz/corpus/pdf_parser/with_annots.pdf differ diff --git a/fuzz/corpus/pdf_parser/with_combed_fields.pdf b/fuzz/corpus/pdf_parser/with_combed_fields.pdf new file mode 100644 index 000000000..6fd151ca3 Binary files /dev/null and b/fuzz/corpus/pdf_parser/with_combed_fields.pdf differ diff --git a/fuzz/corpus/pdf_parser/with_comments.pdf b/fuzz/corpus/pdf_parser/with_comments.pdf new file mode 100644 index 000000000..ec99b75dc Binary files /dev/null and b/fuzz/corpus/pdf_parser/with_comments.pdf differ diff --git a/fuzz/corpus/pdf_parser/with_cropbox.pdf b/fuzz/corpus/pdf_parser/with_cropbox.pdf new file mode 100644 index 000000000..cf3bf9a0c Binary files /dev/null and b/fuzz/corpus/pdf_parser/with_cropbox.pdf differ diff --git a/fuzz/corpus/pdf_parser/with_invalid_objects.pdf b/fuzz/corpus/pdf_parser/with_invalid_objects.pdf new file mode 100644 index 000000000..3633b61a3 Binary files /dev/null and b/fuzz/corpus/pdf_parser/with_invalid_objects.pdf differ diff --git a/fuzz/corpus/pdf_parser/with_invalid_stream_EOL.pdf b/fuzz/corpus/pdf_parser/with_invalid_stream_EOL.pdf new file mode 100644 index 000000000..09583400d Binary files /dev/null and b/fuzz/corpus/pdf_parser/with_invalid_stream_EOL.pdf differ diff --git a/fuzz/corpus/pdf_parser/with_large_page_count.pdf b/fuzz/corpus/pdf_parser/with_large_page_count.pdf new file mode 100644 index 000000000..9899c5829 Binary files /dev/null and b/fuzz/corpus/pdf_parser/with_large_page_count.pdf differ diff --git a/fuzz/corpus/pdf_parser/with_missing_endstream_eol_and_polluted_ctm.pdf b/fuzz/corpus/pdf_parser/with_missing_endstream_eol_and_polluted_ctm.pdf new file mode 100644 index 000000000..6eb0d82c5 Binary files /dev/null and b/fuzz/corpus/pdf_parser/with_missing_endstream_eol_and_polluted_ctm.pdf differ diff --git a/fuzz/corpus/pdf_parser/with_newline_whitespace_in_indirect_object_numbers.pdf b/fuzz/corpus/pdf_parser/with_newline_whitespace_in_indirect_object_numbers.pdf new file mode 100644 index 000000000..93fe72c89 Binary files /dev/null and b/fuzz/corpus/pdf_parser/with_newline_whitespace_in_indirect_object_numbers.pdf differ diff --git a/fuzz/corpus/pdf_parser/with_null_parent_entry.pdf b/fuzz/corpus/pdf_parser/with_null_parent_entry.pdf new file mode 100644 index 000000000..fdcf323c2 Binary files /dev/null and b/fuzz/corpus/pdf_parser/with_null_parent_entry.pdf differ diff --git a/fuzz/corpus/pdf_parser/with_rotated_image_button.pdf b/fuzz/corpus/pdf_parser/with_rotated_image_button.pdf new file mode 100644 index 000000000..76f9a7d28 Binary files /dev/null and b/fuzz/corpus/pdf_parser/with_rotated_image_button.pdf differ diff --git a/fuzz/corpus/pdf_parser/with_signature.pdf b/fuzz/corpus/pdf_parser/with_signature.pdf new file mode 100644 index 000000000..193a2b68d Binary files /dev/null and b/fuzz/corpus/pdf_parser/with_signature.pdf differ diff --git a/fuzz/corpus/pdf_parser/with_update_sections.pdf b/fuzz/corpus/pdf_parser/with_update_sections.pdf new file mode 100644 index 000000000..dd1cb1d23 Binary files /dev/null and b/fuzz/corpus/pdf_parser/with_update_sections.pdf differ diff --git a/fuzz/corpus/pdf_parser/with_viewer_prefs.pdf b/fuzz/corpus/pdf_parser/with_viewer_prefs.pdf new file mode 100644 index 000000000..97cd33c13 Binary files /dev/null and b/fuzz/corpus/pdf_parser/with_viewer_prefs.pdf differ diff --git a/fuzz/corpus/pdf_parser/with_xfa_fields.pdf b/fuzz/corpus/pdf_parser/with_xfa_fields.pdf new file mode 100644 index 000000000..e19c72eca Binary files /dev/null and b/fuzz/corpus/pdf_parser/with_xfa_fields.pdf differ diff --git a/fuzz/corpus/png_embed/PngSuite.png b/fuzz/corpus/png_embed/PngSuite.png new file mode 100644 index 000000000..205460d82 Binary files /dev/null and b/fuzz/corpus/png_embed/PngSuite.png differ diff --git a/fuzz/corpus/png_embed/basi0g01.png b/fuzz/corpus/png_embed/basi0g01.png new file mode 100644 index 000000000..556fa7270 Binary files /dev/null and b/fuzz/corpus/png_embed/basi0g01.png differ diff --git a/fuzz/corpus/png_embed/basi0g02.png b/fuzz/corpus/png_embed/basi0g02.png new file mode 100644 index 000000000..ce09821ef Binary files /dev/null and b/fuzz/corpus/png_embed/basi0g02.png differ diff --git a/fuzz/corpus/png_embed/basi0g04.png b/fuzz/corpus/png_embed/basi0g04.png new file mode 100644 index 000000000..3853273f9 Binary files /dev/null and b/fuzz/corpus/png_embed/basi0g04.png differ diff --git a/fuzz/corpus/png_embed/basi0g08.png b/fuzz/corpus/png_embed/basi0g08.png new file mode 100644 index 000000000..faed8bec4 Binary files /dev/null and b/fuzz/corpus/png_embed/basi0g08.png differ diff --git a/fuzz/corpus/png_embed/basi0g16.png b/fuzz/corpus/png_embed/basi0g16.png new file mode 100644 index 000000000..a9f28165e Binary files /dev/null and b/fuzz/corpus/png_embed/basi0g16.png differ diff --git a/fuzz/corpus/png_embed/basi2c08.png b/fuzz/corpus/png_embed/basi2c08.png new file mode 100644 index 000000000..2aab44d42 Binary files /dev/null and b/fuzz/corpus/png_embed/basi2c08.png differ diff --git a/fuzz/corpus/png_embed/basi2c16.png b/fuzz/corpus/png_embed/basi2c16.png new file mode 100644 index 000000000..cd7e50f91 Binary files /dev/null and b/fuzz/corpus/png_embed/basi2c16.png differ diff --git a/fuzz/corpus/png_embed/basi3p01.png b/fuzz/corpus/png_embed/basi3p01.png new file mode 100644 index 000000000..00a7cea6c Binary files /dev/null and b/fuzz/corpus/png_embed/basi3p01.png differ diff --git a/fuzz/corpus/png_embed/basi3p02.png b/fuzz/corpus/png_embed/basi3p02.png new file mode 100644 index 000000000..bb16b44b3 Binary files /dev/null and b/fuzz/corpus/png_embed/basi3p02.png differ diff --git a/fuzz/corpus/png_embed/basi3p04.png b/fuzz/corpus/png_embed/basi3p04.png new file mode 100644 index 000000000..b4e888e24 Binary files /dev/null and b/fuzz/corpus/png_embed/basi3p04.png differ diff --git a/fuzz/corpus/png_embed/basi3p08.png b/fuzz/corpus/png_embed/basi3p08.png new file mode 100644 index 000000000..50a6d1cac Binary files /dev/null and b/fuzz/corpus/png_embed/basi3p08.png differ diff --git a/fuzz/corpus/png_embed/basi4a08.png b/fuzz/corpus/png_embed/basi4a08.png new file mode 100644 index 000000000..398132be5 Binary files /dev/null and b/fuzz/corpus/png_embed/basi4a08.png differ diff --git a/fuzz/corpus/png_embed/basi4a16.png b/fuzz/corpus/png_embed/basi4a16.png new file mode 100644 index 000000000..51192e731 Binary files /dev/null and b/fuzz/corpus/png_embed/basi4a16.png differ diff --git a/fuzz/corpus/png_embed/basi6a08.png b/fuzz/corpus/png_embed/basi6a08.png new file mode 100644 index 000000000..aecb32e0d Binary files /dev/null and b/fuzz/corpus/png_embed/basi6a08.png differ diff --git a/fuzz/corpus/png_embed/basi6a16.png b/fuzz/corpus/png_embed/basi6a16.png new file mode 100644 index 000000000..4181533ad Binary files /dev/null and b/fuzz/corpus/png_embed/basi6a16.png differ diff --git a/fuzz/corpus/png_embed/basn0g01.png b/fuzz/corpus/png_embed/basn0g01.png new file mode 100644 index 000000000..1d722423a Binary files /dev/null and b/fuzz/corpus/png_embed/basn0g01.png differ diff --git a/fuzz/corpus/png_embed/basn0g02.png b/fuzz/corpus/png_embed/basn0g02.png new file mode 100644 index 000000000..508332418 Binary files /dev/null and b/fuzz/corpus/png_embed/basn0g02.png differ diff --git a/fuzz/corpus/png_embed/basn0g04.png b/fuzz/corpus/png_embed/basn0g04.png new file mode 100644 index 000000000..0bf368786 Binary files /dev/null and b/fuzz/corpus/png_embed/basn0g04.png differ diff --git a/fuzz/corpus/png_embed/basn0g08.png b/fuzz/corpus/png_embed/basn0g08.png new file mode 100644 index 000000000..23c82379a Binary files /dev/null and b/fuzz/corpus/png_embed/basn0g08.png differ diff --git a/fuzz/corpus/png_embed/basn0g16.png b/fuzz/corpus/png_embed/basn0g16.png new file mode 100644 index 000000000..e7c82f78e Binary files /dev/null and b/fuzz/corpus/png_embed/basn0g16.png differ diff --git a/fuzz/corpus/png_embed/basn2c08.png b/fuzz/corpus/png_embed/basn2c08.png new file mode 100644 index 000000000..db5ad1586 Binary files /dev/null and b/fuzz/corpus/png_embed/basn2c08.png differ diff --git a/fuzz/corpus/png_embed/basn2c16.png b/fuzz/corpus/png_embed/basn2c16.png new file mode 100644 index 000000000..50c1cb91a Binary files /dev/null and b/fuzz/corpus/png_embed/basn2c16.png differ diff --git a/fuzz/corpus/png_embed/basn3p01.png b/fuzz/corpus/png_embed/basn3p01.png new file mode 100644 index 000000000..b145c2b8e Binary files /dev/null and b/fuzz/corpus/png_embed/basn3p01.png differ diff --git a/fuzz/corpus/png_embed/basn3p02.png b/fuzz/corpus/png_embed/basn3p02.png new file mode 100644 index 000000000..8985b3d81 Binary files /dev/null and b/fuzz/corpus/png_embed/basn3p02.png differ diff --git a/fuzz/corpus/png_embed/basn3p04.png b/fuzz/corpus/png_embed/basn3p04.png new file mode 100644 index 000000000..0fbf9e827 Binary files /dev/null and b/fuzz/corpus/png_embed/basn3p04.png differ diff --git a/fuzz/corpus/png_embed/basn3p08.png b/fuzz/corpus/png_embed/basn3p08.png new file mode 100644 index 000000000..0ddad07e5 Binary files /dev/null and b/fuzz/corpus/png_embed/basn3p08.png differ diff --git a/fuzz/corpus/png_embed/basn4a08.png b/fuzz/corpus/png_embed/basn4a08.png new file mode 100644 index 000000000..3e1305220 Binary files /dev/null and b/fuzz/corpus/png_embed/basn4a08.png differ diff --git a/fuzz/corpus/png_embed/basn4a16.png b/fuzz/corpus/png_embed/basn4a16.png new file mode 100644 index 000000000..8243644d0 Binary files /dev/null and b/fuzz/corpus/png_embed/basn4a16.png differ diff --git a/fuzz/corpus/png_embed/basn6a08.png b/fuzz/corpus/png_embed/basn6a08.png new file mode 100644 index 000000000..e60873876 Binary files /dev/null and b/fuzz/corpus/png_embed/basn6a08.png differ diff --git a/fuzz/corpus/png_embed/basn6a16.png b/fuzz/corpus/png_embed/basn6a16.png new file mode 100644 index 000000000..984a99525 Binary files /dev/null and b/fuzz/corpus/png_embed/basn6a16.png differ diff --git a/fuzz/corpus/png_embed/bgai4a08.png b/fuzz/corpus/png_embed/bgai4a08.png new file mode 100644 index 000000000..398132be5 Binary files /dev/null and b/fuzz/corpus/png_embed/bgai4a08.png differ diff --git a/fuzz/corpus/png_embed/bgai4a16.png b/fuzz/corpus/png_embed/bgai4a16.png new file mode 100644 index 000000000..51192e731 Binary files /dev/null and b/fuzz/corpus/png_embed/bgai4a16.png differ diff --git a/fuzz/corpus/png_embed/bgan6a08.png b/fuzz/corpus/png_embed/bgan6a08.png new file mode 100644 index 000000000..e60873876 Binary files /dev/null and b/fuzz/corpus/png_embed/bgan6a08.png differ diff --git a/fuzz/corpus/png_embed/bgan6a16.png b/fuzz/corpus/png_embed/bgan6a16.png new file mode 100644 index 000000000..984a99525 Binary files /dev/null and b/fuzz/corpus/png_embed/bgan6a16.png differ diff --git a/fuzz/corpus/png_embed/bgbn4a08.png b/fuzz/corpus/png_embed/bgbn4a08.png new file mode 100644 index 000000000..7cbefc3bf Binary files /dev/null and b/fuzz/corpus/png_embed/bgbn4a08.png differ diff --git a/fuzz/corpus/png_embed/bggn4a16.png b/fuzz/corpus/png_embed/bggn4a16.png new file mode 100644 index 000000000..13fd85ba1 Binary files /dev/null and b/fuzz/corpus/png_embed/bggn4a16.png differ diff --git a/fuzz/corpus/png_embed/bgwn6a08.png b/fuzz/corpus/png_embed/bgwn6a08.png new file mode 100644 index 000000000..a67ff205b Binary files /dev/null and b/fuzz/corpus/png_embed/bgwn6a08.png differ diff --git a/fuzz/corpus/png_embed/bgyn6a16.png b/fuzz/corpus/png_embed/bgyn6a16.png new file mode 100644 index 000000000..ae3e9be58 Binary files /dev/null and b/fuzz/corpus/png_embed/bgyn6a16.png differ diff --git a/fuzz/corpus/png_embed/ccwn2c08.png b/fuzz/corpus/png_embed/ccwn2c08.png new file mode 100644 index 000000000..47c24817b Binary files /dev/null and b/fuzz/corpus/png_embed/ccwn2c08.png differ diff --git a/fuzz/corpus/png_embed/ccwn3p08.png b/fuzz/corpus/png_embed/ccwn3p08.png new file mode 100644 index 000000000..8bb2c1098 Binary files /dev/null and b/fuzz/corpus/png_embed/ccwn3p08.png differ diff --git a/fuzz/corpus/png_embed/cdfn2c08.png b/fuzz/corpus/png_embed/cdfn2c08.png new file mode 100644 index 000000000..559e5261e Binary files /dev/null and b/fuzz/corpus/png_embed/cdfn2c08.png differ diff --git a/fuzz/corpus/png_embed/cdhn2c08.png b/fuzz/corpus/png_embed/cdhn2c08.png new file mode 100644 index 000000000..3e07e8ecb Binary files /dev/null and b/fuzz/corpus/png_embed/cdhn2c08.png differ diff --git a/fuzz/corpus/png_embed/cdsn2c08.png b/fuzz/corpus/png_embed/cdsn2c08.png new file mode 100644 index 000000000..076c32cc0 Binary files /dev/null and b/fuzz/corpus/png_embed/cdsn2c08.png differ diff --git a/fuzz/corpus/png_embed/cdun2c08.png b/fuzz/corpus/png_embed/cdun2c08.png new file mode 100644 index 000000000..846033be6 Binary files /dev/null and b/fuzz/corpus/png_embed/cdun2c08.png differ diff --git a/fuzz/corpus/png_embed/ch1n3p04.png b/fuzz/corpus/png_embed/ch1n3p04.png new file mode 100644 index 000000000..17cd12dfc Binary files /dev/null and b/fuzz/corpus/png_embed/ch1n3p04.png differ diff --git a/fuzz/corpus/png_embed/ch2n3p08.png b/fuzz/corpus/png_embed/ch2n3p08.png new file mode 100644 index 000000000..25c17987a Binary files /dev/null and b/fuzz/corpus/png_embed/ch2n3p08.png differ diff --git a/fuzz/corpus/png_embed/cm0n0g04.png b/fuzz/corpus/png_embed/cm0n0g04.png new file mode 100644 index 000000000..9fba5db3b Binary files /dev/null and b/fuzz/corpus/png_embed/cm0n0g04.png differ diff --git a/fuzz/corpus/png_embed/cm7n0g04.png b/fuzz/corpus/png_embed/cm7n0g04.png new file mode 100644 index 000000000..f7dc46e68 Binary files /dev/null and b/fuzz/corpus/png_embed/cm7n0g04.png differ diff --git a/fuzz/corpus/png_embed/cm9n0g04.png b/fuzz/corpus/png_embed/cm9n0g04.png new file mode 100644 index 000000000..dd70911ad Binary files /dev/null and b/fuzz/corpus/png_embed/cm9n0g04.png differ diff --git a/fuzz/corpus/png_embed/cs3n2c16.png b/fuzz/corpus/png_embed/cs3n2c16.png new file mode 100644 index 000000000..bf5fd20a2 Binary files /dev/null and b/fuzz/corpus/png_embed/cs3n2c16.png differ diff --git a/fuzz/corpus/png_embed/cs3n3p08.png b/fuzz/corpus/png_embed/cs3n3p08.png new file mode 100644 index 000000000..f4a66237b Binary files /dev/null and b/fuzz/corpus/png_embed/cs3n3p08.png differ diff --git a/fuzz/corpus/png_embed/cs5n2c08.png b/fuzz/corpus/png_embed/cs5n2c08.png new file mode 100644 index 000000000..40f947c33 Binary files /dev/null and b/fuzz/corpus/png_embed/cs5n2c08.png differ diff --git a/fuzz/corpus/png_embed/cs5n3p08.png b/fuzz/corpus/png_embed/cs5n3p08.png new file mode 100644 index 000000000..dfd6e6e6e Binary files /dev/null and b/fuzz/corpus/png_embed/cs5n3p08.png differ diff --git a/fuzz/corpus/png_embed/cs8n2c08.png b/fuzz/corpus/png_embed/cs8n2c08.png new file mode 100644 index 000000000..8e01d3294 Binary files /dev/null and b/fuzz/corpus/png_embed/cs8n2c08.png differ diff --git a/fuzz/corpus/png_embed/cs8n3p08.png b/fuzz/corpus/png_embed/cs8n3p08.png new file mode 100644 index 000000000..a44066eb6 Binary files /dev/null and b/fuzz/corpus/png_embed/cs8n3p08.png differ diff --git a/fuzz/corpus/png_embed/ct0n0g04.png b/fuzz/corpus/png_embed/ct0n0g04.png new file mode 100644 index 000000000..40d1e062f Binary files /dev/null and b/fuzz/corpus/png_embed/ct0n0g04.png differ diff --git a/fuzz/corpus/png_embed/ct1n0g04.png b/fuzz/corpus/png_embed/ct1n0g04.png new file mode 100644 index 000000000..3ba110aa7 Binary files /dev/null and b/fuzz/corpus/png_embed/ct1n0g04.png differ diff --git a/fuzz/corpus/png_embed/cten0g04.png b/fuzz/corpus/png_embed/cten0g04.png new file mode 100644 index 000000000..a6a56faf2 Binary files /dev/null and b/fuzz/corpus/png_embed/cten0g04.png differ diff --git a/fuzz/corpus/png_embed/ctfn0g04.png b/fuzz/corpus/png_embed/ctfn0g04.png new file mode 100644 index 000000000..353873ebb Binary files /dev/null and b/fuzz/corpus/png_embed/ctfn0g04.png differ diff --git a/fuzz/corpus/png_embed/ctgn0g04.png b/fuzz/corpus/png_embed/ctgn0g04.png new file mode 100644 index 000000000..453f2b0a4 Binary files /dev/null and b/fuzz/corpus/png_embed/ctgn0g04.png differ diff --git a/fuzz/corpus/png_embed/cthn0g04.png b/fuzz/corpus/png_embed/cthn0g04.png new file mode 100644 index 000000000..8fce253e6 Binary files /dev/null and b/fuzz/corpus/png_embed/cthn0g04.png differ diff --git a/fuzz/corpus/png_embed/ctjn0g04.png b/fuzz/corpus/png_embed/ctjn0g04.png new file mode 100644 index 000000000..a77b8d2fe Binary files /dev/null and b/fuzz/corpus/png_embed/ctjn0g04.png differ diff --git a/fuzz/corpus/png_embed/ctzn0g04.png b/fuzz/corpus/png_embed/ctzn0g04.png new file mode 100644 index 000000000..b4401c9cf Binary files /dev/null and b/fuzz/corpus/png_embed/ctzn0g04.png differ diff --git a/fuzz/corpus/png_embed/etwe.png b/fuzz/corpus/png_embed/etwe.png new file mode 100644 index 000000000..84d225898 Binary files /dev/null and b/fuzz/corpus/png_embed/etwe.png differ diff --git a/fuzz/corpus/png_embed/exif2c08.png b/fuzz/corpus/png_embed/exif2c08.png new file mode 100644 index 000000000..56eb73499 Binary files /dev/null and b/fuzz/corpus/png_embed/exif2c08.png differ diff --git a/fuzz/corpus/png_embed/f00n0g08.png b/fuzz/corpus/png_embed/f00n0g08.png new file mode 100644 index 000000000..45a007596 Binary files /dev/null and b/fuzz/corpus/png_embed/f00n0g08.png differ diff --git a/fuzz/corpus/png_embed/f00n2c08.png b/fuzz/corpus/png_embed/f00n2c08.png new file mode 100644 index 000000000..d6a1ffff6 Binary files /dev/null and b/fuzz/corpus/png_embed/f00n2c08.png differ diff --git a/fuzz/corpus/png_embed/f01n0g08.png b/fuzz/corpus/png_embed/f01n0g08.png new file mode 100644 index 000000000..4a1107b46 Binary files /dev/null and b/fuzz/corpus/png_embed/f01n0g08.png differ diff --git a/fuzz/corpus/png_embed/f01n2c08.png b/fuzz/corpus/png_embed/f01n2c08.png new file mode 100644 index 000000000..26fee958c Binary files /dev/null and b/fuzz/corpus/png_embed/f01n2c08.png differ diff --git a/fuzz/corpus/png_embed/f02n0g08.png b/fuzz/corpus/png_embed/f02n0g08.png new file mode 100644 index 000000000..bfe410c5e Binary files /dev/null and b/fuzz/corpus/png_embed/f02n0g08.png differ diff --git a/fuzz/corpus/png_embed/f02n2c08.png b/fuzz/corpus/png_embed/f02n2c08.png new file mode 100644 index 000000000..e590f1234 Binary files /dev/null and b/fuzz/corpus/png_embed/f02n2c08.png differ diff --git a/fuzz/corpus/png_embed/f03n0g08.png b/fuzz/corpus/png_embed/f03n0g08.png new file mode 100644 index 000000000..ed01e2923 Binary files /dev/null and b/fuzz/corpus/png_embed/f03n0g08.png differ diff --git a/fuzz/corpus/png_embed/f03n2c08.png b/fuzz/corpus/png_embed/f03n2c08.png new file mode 100644 index 000000000..758115059 Binary files /dev/null and b/fuzz/corpus/png_embed/f03n2c08.png differ diff --git a/fuzz/corpus/png_embed/f04n0g08.png b/fuzz/corpus/png_embed/f04n0g08.png new file mode 100644 index 000000000..663fdae3e Binary files /dev/null and b/fuzz/corpus/png_embed/f04n0g08.png differ diff --git a/fuzz/corpus/png_embed/f04n2c08.png b/fuzz/corpus/png_embed/f04n2c08.png new file mode 100644 index 000000000..3c8b5116e Binary files /dev/null and b/fuzz/corpus/png_embed/f04n2c08.png differ diff --git a/fuzz/corpus/png_embed/f99n0g04.png b/fuzz/corpus/png_embed/f99n0g04.png new file mode 100644 index 000000000..0b521c1d5 Binary files /dev/null and b/fuzz/corpus/png_embed/f99n0g04.png differ diff --git a/fuzz/corpus/png_embed/g03n0g16.png b/fuzz/corpus/png_embed/g03n0g16.png new file mode 100644 index 000000000..41083ca80 Binary files /dev/null and b/fuzz/corpus/png_embed/g03n0g16.png differ diff --git a/fuzz/corpus/png_embed/g03n2c08.png b/fuzz/corpus/png_embed/g03n2c08.png new file mode 100644 index 000000000..a9354dbee Binary files /dev/null and b/fuzz/corpus/png_embed/g03n2c08.png differ diff --git a/fuzz/corpus/png_embed/g03n3p04.png b/fuzz/corpus/png_embed/g03n3p04.png new file mode 100644 index 000000000..60396c95a Binary files /dev/null and b/fuzz/corpus/png_embed/g03n3p04.png differ diff --git a/fuzz/corpus/png_embed/g04n0g16.png b/fuzz/corpus/png_embed/g04n0g16.png new file mode 100644 index 000000000..32395b76c Binary files /dev/null and b/fuzz/corpus/png_embed/g04n0g16.png differ diff --git a/fuzz/corpus/png_embed/g04n2c08.png b/fuzz/corpus/png_embed/g04n2c08.png new file mode 100644 index 000000000..a652b0ce8 Binary files /dev/null and b/fuzz/corpus/png_embed/g04n2c08.png differ diff --git a/fuzz/corpus/png_embed/g04n3p04.png b/fuzz/corpus/png_embed/g04n3p04.png new file mode 100644 index 000000000..5661cc313 Binary files /dev/null and b/fuzz/corpus/png_embed/g04n3p04.png differ diff --git a/fuzz/corpus/png_embed/g05n0g16.png b/fuzz/corpus/png_embed/g05n0g16.png new file mode 100644 index 000000000..70b37f01e Binary files /dev/null and b/fuzz/corpus/png_embed/g05n0g16.png differ diff --git a/fuzz/corpus/png_embed/g05n2c08.png b/fuzz/corpus/png_embed/g05n2c08.png new file mode 100644 index 000000000..932c13653 Binary files /dev/null and b/fuzz/corpus/png_embed/g05n2c08.png differ diff --git a/fuzz/corpus/png_embed/g05n3p04.png b/fuzz/corpus/png_embed/g05n3p04.png new file mode 100644 index 000000000..961993058 Binary files /dev/null and b/fuzz/corpus/png_embed/g05n3p04.png differ diff --git a/fuzz/corpus/png_embed/g07n0g16.png b/fuzz/corpus/png_embed/g07n0g16.png new file mode 100644 index 000000000..d6a47c2d5 Binary files /dev/null and b/fuzz/corpus/png_embed/g07n0g16.png differ diff --git a/fuzz/corpus/png_embed/g07n2c08.png b/fuzz/corpus/png_embed/g07n2c08.png new file mode 100644 index 000000000..597346460 Binary files /dev/null and b/fuzz/corpus/png_embed/g07n2c08.png differ diff --git a/fuzz/corpus/png_embed/g07n3p04.png b/fuzz/corpus/png_embed/g07n3p04.png new file mode 100644 index 000000000..c73fb6136 Binary files /dev/null and b/fuzz/corpus/png_embed/g07n3p04.png differ diff --git a/fuzz/corpus/png_embed/g10n0g16.png b/fuzz/corpus/png_embed/g10n0g16.png new file mode 100644 index 000000000..85f2c958e Binary files /dev/null and b/fuzz/corpus/png_embed/g10n0g16.png differ diff --git a/fuzz/corpus/png_embed/g10n2c08.png b/fuzz/corpus/png_embed/g10n2c08.png new file mode 100644 index 000000000..b3039970c Binary files /dev/null and b/fuzz/corpus/png_embed/g10n2c08.png differ diff --git a/fuzz/corpus/png_embed/g10n3p04.png b/fuzz/corpus/png_embed/g10n3p04.png new file mode 100644 index 000000000..1b6a6be2c Binary files /dev/null and b/fuzz/corpus/png_embed/g10n3p04.png differ diff --git a/fuzz/corpus/png_embed/g25n0g16.png b/fuzz/corpus/png_embed/g25n0g16.png new file mode 100644 index 000000000..a9f6787c7 Binary files /dev/null and b/fuzz/corpus/png_embed/g25n0g16.png differ diff --git a/fuzz/corpus/png_embed/g25n2c08.png b/fuzz/corpus/png_embed/g25n2c08.png new file mode 100644 index 000000000..03f505a64 Binary files /dev/null and b/fuzz/corpus/png_embed/g25n2c08.png differ diff --git a/fuzz/corpus/png_embed/g25n3p04.png b/fuzz/corpus/png_embed/g25n3p04.png new file mode 100644 index 000000000..4f943c617 Binary files /dev/null and b/fuzz/corpus/png_embed/g25n3p04.png differ diff --git a/fuzz/corpus/png_embed/greyscale_bird.png b/fuzz/corpus/png_embed/greyscale_bird.png new file mode 100644 index 000000000..5068c3271 Binary files /dev/null and b/fuzz/corpus/png_embed/greyscale_bird.png differ diff --git a/fuzz/corpus/png_embed/mario_emblem.png b/fuzz/corpus/png_embed/mario_emblem.png new file mode 100644 index 000000000..06f03cef6 Binary files /dev/null and b/fuzz/corpus/png_embed/mario_emblem.png differ diff --git a/fuzz/corpus/png_embed/minions_banana_alpha.png b/fuzz/corpus/png_embed/minions_banana_alpha.png new file mode 100644 index 000000000..d23036dec Binary files /dev/null and b/fuzz/corpus/png_embed/minions_banana_alpha.png differ diff --git a/fuzz/corpus/png_embed/minions_banana_no_alpha.png b/fuzz/corpus/png_embed/minions_banana_no_alpha.png new file mode 100644 index 000000000..0708d93fd Binary files /dev/null and b/fuzz/corpus/png_embed/minions_banana_no_alpha.png differ diff --git a/fuzz/corpus/png_embed/minions_banana_no_alpha_resized.png b/fuzz/corpus/png_embed/minions_banana_no_alpha_resized.png new file mode 100644 index 000000000..130e2163a Binary files /dev/null and b/fuzz/corpus/png_embed/minions_banana_no_alpha_resized.png differ diff --git a/fuzz/corpus/png_embed/oi1n0g16.png b/fuzz/corpus/png_embed/oi1n0g16.png new file mode 100644 index 000000000..e7c82f78e Binary files /dev/null and b/fuzz/corpus/png_embed/oi1n0g16.png differ diff --git a/fuzz/corpus/png_embed/oi1n2c16.png b/fuzz/corpus/png_embed/oi1n2c16.png new file mode 100644 index 000000000..50c1cb91a Binary files /dev/null and b/fuzz/corpus/png_embed/oi1n2c16.png differ diff --git a/fuzz/corpus/png_embed/oi2n0g16.png b/fuzz/corpus/png_embed/oi2n0g16.png new file mode 100644 index 000000000..14d64c583 Binary files /dev/null and b/fuzz/corpus/png_embed/oi2n0g16.png differ diff --git a/fuzz/corpus/png_embed/oi2n2c16.png b/fuzz/corpus/png_embed/oi2n2c16.png new file mode 100644 index 000000000..4c2e3e335 Binary files /dev/null and b/fuzz/corpus/png_embed/oi2n2c16.png differ diff --git a/fuzz/corpus/png_embed/oi4n0g16.png b/fuzz/corpus/png_embed/oi4n0g16.png new file mode 100644 index 000000000..69e73ede3 Binary files /dev/null and b/fuzz/corpus/png_embed/oi4n0g16.png differ diff --git a/fuzz/corpus/png_embed/oi4n2c16.png b/fuzz/corpus/png_embed/oi4n2c16.png new file mode 100644 index 000000000..93691e373 Binary files /dev/null and b/fuzz/corpus/png_embed/oi4n2c16.png differ diff --git a/fuzz/corpus/png_embed/oi9n0g16.png b/fuzz/corpus/png_embed/oi9n0g16.png new file mode 100644 index 000000000..924841357 Binary files /dev/null and b/fuzz/corpus/png_embed/oi9n0g16.png differ diff --git a/fuzz/corpus/png_embed/oi9n2c16.png b/fuzz/corpus/png_embed/oi9n2c16.png new file mode 100644 index 000000000..f0512e49f Binary files /dev/null and b/fuzz/corpus/png_embed/oi9n2c16.png differ diff --git a/fuzz/corpus/png_embed/pp0n2c16.png b/fuzz/corpus/png_embed/pp0n2c16.png new file mode 100644 index 000000000..8f2aad733 Binary files /dev/null and b/fuzz/corpus/png_embed/pp0n2c16.png differ diff --git a/fuzz/corpus/png_embed/pp0n6a08.png b/fuzz/corpus/png_embed/pp0n6a08.png new file mode 100644 index 000000000..4ed7a30e4 Binary files /dev/null and b/fuzz/corpus/png_embed/pp0n6a08.png differ diff --git a/fuzz/corpus/png_embed/ps1n0g08.png b/fuzz/corpus/png_embed/ps1n0g08.png new file mode 100644 index 000000000..99625fa4b Binary files /dev/null and b/fuzz/corpus/png_embed/ps1n0g08.png differ diff --git a/fuzz/corpus/png_embed/ps1n2c16.png b/fuzz/corpus/png_embed/ps1n2c16.png new file mode 100644 index 000000000..0c7a6b380 Binary files /dev/null and b/fuzz/corpus/png_embed/ps1n2c16.png differ diff --git a/fuzz/corpus/png_embed/ps2n0g08.png b/fuzz/corpus/png_embed/ps2n0g08.png new file mode 100644 index 000000000..90b297968 Binary files /dev/null and b/fuzz/corpus/png_embed/ps2n0g08.png differ diff --git a/fuzz/corpus/png_embed/ps2n2c16.png b/fuzz/corpus/png_embed/ps2n2c16.png new file mode 100644 index 000000000..a4a181e4e Binary files /dev/null and b/fuzz/corpus/png_embed/ps2n2c16.png differ diff --git a/fuzz/corpus/png_embed/s01i3p01.png b/fuzz/corpus/png_embed/s01i3p01.png new file mode 100644 index 000000000..6c0fad1fc Binary files /dev/null and b/fuzz/corpus/png_embed/s01i3p01.png differ diff --git a/fuzz/corpus/png_embed/s01n3p01.png b/fuzz/corpus/png_embed/s01n3p01.png new file mode 100644 index 000000000..cb2c8c782 Binary files /dev/null and b/fuzz/corpus/png_embed/s01n3p01.png differ diff --git a/fuzz/corpus/png_embed/s02i3p01.png b/fuzz/corpus/png_embed/s02i3p01.png new file mode 100644 index 000000000..2defaed91 Binary files /dev/null and b/fuzz/corpus/png_embed/s02i3p01.png differ diff --git a/fuzz/corpus/png_embed/s02n3p01.png b/fuzz/corpus/png_embed/s02n3p01.png new file mode 100644 index 000000000..2b1b66964 Binary files /dev/null and b/fuzz/corpus/png_embed/s02n3p01.png differ diff --git a/fuzz/corpus/png_embed/s03i3p01.png b/fuzz/corpus/png_embed/s03i3p01.png new file mode 100644 index 000000000..c23fdc463 Binary files /dev/null and b/fuzz/corpus/png_embed/s03i3p01.png differ diff --git a/fuzz/corpus/png_embed/s03n3p01.png b/fuzz/corpus/png_embed/s03n3p01.png new file mode 100644 index 000000000..6d96ee4f8 Binary files /dev/null and b/fuzz/corpus/png_embed/s03n3p01.png differ diff --git a/fuzz/corpus/png_embed/s04i3p01.png b/fuzz/corpus/png_embed/s04i3p01.png new file mode 100644 index 000000000..0e710c2c3 Binary files /dev/null and b/fuzz/corpus/png_embed/s04i3p01.png differ diff --git a/fuzz/corpus/png_embed/s04n3p01.png b/fuzz/corpus/png_embed/s04n3p01.png new file mode 100644 index 000000000..956396c45 Binary files /dev/null and b/fuzz/corpus/png_embed/s04n3p01.png differ diff --git a/fuzz/corpus/png_embed/s05i3p02.png b/fuzz/corpus/png_embed/s05i3p02.png new file mode 100644 index 000000000..d14cbd351 Binary files /dev/null and b/fuzz/corpus/png_embed/s05i3p02.png differ diff --git a/fuzz/corpus/png_embed/s05n3p02.png b/fuzz/corpus/png_embed/s05n3p02.png new file mode 100644 index 000000000..bf940f057 Binary files /dev/null and b/fuzz/corpus/png_embed/s05n3p02.png differ diff --git a/fuzz/corpus/png_embed/s06i3p02.png b/fuzz/corpus/png_embed/s06i3p02.png new file mode 100644 index 000000000..456ada320 Binary files /dev/null and b/fuzz/corpus/png_embed/s06i3p02.png differ diff --git a/fuzz/corpus/png_embed/s06n3p02.png b/fuzz/corpus/png_embed/s06n3p02.png new file mode 100644 index 000000000..501064dc2 Binary files /dev/null and b/fuzz/corpus/png_embed/s06n3p02.png differ diff --git a/fuzz/corpus/png_embed/s07i3p02.png b/fuzz/corpus/png_embed/s07i3p02.png new file mode 100644 index 000000000..44b66bab9 Binary files /dev/null and b/fuzz/corpus/png_embed/s07i3p02.png differ diff --git a/fuzz/corpus/png_embed/s07n3p02.png b/fuzz/corpus/png_embed/s07n3p02.png new file mode 100644 index 000000000..6a582593d Binary files /dev/null and b/fuzz/corpus/png_embed/s07n3p02.png differ diff --git a/fuzz/corpus/png_embed/s08i3p02.png b/fuzz/corpus/png_embed/s08i3p02.png new file mode 100644 index 000000000..acf74f3fc Binary files /dev/null and b/fuzz/corpus/png_embed/s08i3p02.png differ diff --git a/fuzz/corpus/png_embed/s08n3p02.png b/fuzz/corpus/png_embed/s08n3p02.png new file mode 100644 index 000000000..b7094e1b4 Binary files /dev/null and b/fuzz/corpus/png_embed/s08n3p02.png differ diff --git a/fuzz/corpus/png_embed/s09i3p02.png b/fuzz/corpus/png_embed/s09i3p02.png new file mode 100644 index 000000000..0bfae8e45 Binary files /dev/null and b/fuzz/corpus/png_embed/s09i3p02.png differ diff --git a/fuzz/corpus/png_embed/s09n3p02.png b/fuzz/corpus/png_embed/s09n3p02.png new file mode 100644 index 000000000..711ab8245 Binary files /dev/null and b/fuzz/corpus/png_embed/s09n3p02.png differ diff --git a/fuzz/corpus/png_embed/s32i3p04.png b/fuzz/corpus/png_embed/s32i3p04.png new file mode 100644 index 000000000..0841910b7 Binary files /dev/null and b/fuzz/corpus/png_embed/s32i3p04.png differ diff --git a/fuzz/corpus/png_embed/s32n3p04.png b/fuzz/corpus/png_embed/s32n3p04.png new file mode 100644 index 000000000..fa58e3e3f Binary files /dev/null and b/fuzz/corpus/png_embed/s32n3p04.png differ diff --git a/fuzz/corpus/png_embed/s33i3p04.png b/fuzz/corpus/png_embed/s33i3p04.png new file mode 100644 index 000000000..ab0dc14ab Binary files /dev/null and b/fuzz/corpus/png_embed/s33i3p04.png differ diff --git a/fuzz/corpus/png_embed/s33n3p04.png b/fuzz/corpus/png_embed/s33n3p04.png new file mode 100644 index 000000000..764f1a3dc Binary files /dev/null and b/fuzz/corpus/png_embed/s33n3p04.png differ diff --git a/fuzz/corpus/png_embed/s34i3p04.png b/fuzz/corpus/png_embed/s34i3p04.png new file mode 100644 index 000000000..bd99039be Binary files /dev/null and b/fuzz/corpus/png_embed/s34i3p04.png differ diff --git a/fuzz/corpus/png_embed/s34n3p04.png b/fuzz/corpus/png_embed/s34n3p04.png new file mode 100644 index 000000000..9cbc68b3b Binary files /dev/null and b/fuzz/corpus/png_embed/s34n3p04.png differ diff --git a/fuzz/corpus/png_embed/s35i3p04.png b/fuzz/corpus/png_embed/s35i3p04.png new file mode 100644 index 000000000..e2a5e0a65 Binary files /dev/null and b/fuzz/corpus/png_embed/s35i3p04.png differ diff --git a/fuzz/corpus/png_embed/s35n3p04.png b/fuzz/corpus/png_embed/s35n3p04.png new file mode 100644 index 000000000..90b892eba Binary files /dev/null and b/fuzz/corpus/png_embed/s35n3p04.png differ diff --git a/fuzz/corpus/png_embed/s36i3p04.png b/fuzz/corpus/png_embed/s36i3p04.png new file mode 100644 index 000000000..eb61b6f9a Binary files /dev/null and b/fuzz/corpus/png_embed/s36i3p04.png differ diff --git a/fuzz/corpus/png_embed/s36n3p04.png b/fuzz/corpus/png_embed/s36n3p04.png new file mode 100644 index 000000000..b38d17977 Binary files /dev/null and b/fuzz/corpus/png_embed/s36n3p04.png differ diff --git a/fuzz/corpus/png_embed/s37i3p04.png b/fuzz/corpus/png_embed/s37i3p04.png new file mode 100644 index 000000000..6e2b1e9b7 Binary files /dev/null and b/fuzz/corpus/png_embed/s37i3p04.png differ diff --git a/fuzz/corpus/png_embed/s37n3p04.png b/fuzz/corpus/png_embed/s37n3p04.png new file mode 100644 index 000000000..4d3054da5 Binary files /dev/null and b/fuzz/corpus/png_embed/s37n3p04.png differ diff --git a/fuzz/corpus/png_embed/s38i3p04.png b/fuzz/corpus/png_embed/s38i3p04.png new file mode 100644 index 000000000..a0a8a140a Binary files /dev/null and b/fuzz/corpus/png_embed/s38i3p04.png differ diff --git a/fuzz/corpus/png_embed/s38n3p04.png b/fuzz/corpus/png_embed/s38n3p04.png new file mode 100644 index 000000000..1233ed048 Binary files /dev/null and b/fuzz/corpus/png_embed/s38n3p04.png differ diff --git a/fuzz/corpus/png_embed/s39i3p04.png b/fuzz/corpus/png_embed/s39i3p04.png new file mode 100644 index 000000000..04fee93ea Binary files /dev/null and b/fuzz/corpus/png_embed/s39i3p04.png differ diff --git a/fuzz/corpus/png_embed/s39n3p04.png b/fuzz/corpus/png_embed/s39n3p04.png new file mode 100644 index 000000000..c750100d5 Binary files /dev/null and b/fuzz/corpus/png_embed/s39n3p04.png differ diff --git a/fuzz/corpus/png_embed/s40i3p04.png b/fuzz/corpus/png_embed/s40i3p04.png new file mode 100644 index 000000000..68f358b82 Binary files /dev/null and b/fuzz/corpus/png_embed/s40i3p04.png differ diff --git a/fuzz/corpus/png_embed/s40n3p04.png b/fuzz/corpus/png_embed/s40n3p04.png new file mode 100644 index 000000000..864b6b967 Binary files /dev/null and b/fuzz/corpus/png_embed/s40n3p04.png differ diff --git a/fuzz/corpus/png_embed/self_drive.png b/fuzz/corpus/png_embed/self_drive.png new file mode 100644 index 000000000..e5bd28131 Binary files /dev/null and b/fuzz/corpus/png_embed/self_drive.png differ diff --git a/fuzz/corpus/png_embed/small_mario.png b/fuzz/corpus/png_embed/small_mario.png new file mode 100644 index 000000000..526ffffaa Binary files /dev/null and b/fuzz/corpus/png_embed/small_mario.png differ diff --git a/fuzz/corpus/png_embed/small_mario_resized.png b/fuzz/corpus/png_embed/small_mario_resized.png new file mode 100644 index 000000000..16c07f9bf Binary files /dev/null and b/fuzz/corpus/png_embed/small_mario_resized.png differ diff --git a/fuzz/corpus/png_embed/tbbn0g04.png b/fuzz/corpus/png_embed/tbbn0g04.png new file mode 100644 index 000000000..39a7050d2 Binary files /dev/null and b/fuzz/corpus/png_embed/tbbn0g04.png differ diff --git a/fuzz/corpus/png_embed/tbbn2c16.png b/fuzz/corpus/png_embed/tbbn2c16.png new file mode 100644 index 000000000..dd3168e5c Binary files /dev/null and b/fuzz/corpus/png_embed/tbbn2c16.png differ diff --git a/fuzz/corpus/png_embed/tbbn3p08.png b/fuzz/corpus/png_embed/tbbn3p08.png new file mode 100644 index 000000000..0ede3574d Binary files /dev/null and b/fuzz/corpus/png_embed/tbbn3p08.png differ diff --git a/fuzz/corpus/png_embed/tbgn2c16.png b/fuzz/corpus/png_embed/tbgn2c16.png new file mode 100644 index 000000000..85cec395c Binary files /dev/null and b/fuzz/corpus/png_embed/tbgn2c16.png differ diff --git a/fuzz/corpus/png_embed/tbgn3p08.png b/fuzz/corpus/png_embed/tbgn3p08.png new file mode 100644 index 000000000..8cf2e6fb6 Binary files /dev/null and b/fuzz/corpus/png_embed/tbgn3p08.png differ diff --git a/fuzz/corpus/png_embed/tbrn2c08.png b/fuzz/corpus/png_embed/tbrn2c08.png new file mode 100644 index 000000000..5cca0d621 Binary files /dev/null and b/fuzz/corpus/png_embed/tbrn2c08.png differ diff --git a/fuzz/corpus/png_embed/tbwn0g16.png b/fuzz/corpus/png_embed/tbwn0g16.png new file mode 100644 index 000000000..99bdeed2b Binary files /dev/null and b/fuzz/corpus/png_embed/tbwn0g16.png differ diff --git a/fuzz/corpus/png_embed/tbwn3p08.png b/fuzz/corpus/png_embed/tbwn3p08.png new file mode 100644 index 000000000..eacab7a14 Binary files /dev/null and b/fuzz/corpus/png_embed/tbwn3p08.png differ diff --git a/fuzz/corpus/png_embed/tbyn3p08.png b/fuzz/corpus/png_embed/tbyn3p08.png new file mode 100644 index 000000000..656db0989 Binary files /dev/null and b/fuzz/corpus/png_embed/tbyn3p08.png differ diff --git a/fuzz/corpus/png_embed/tm3n3p02.png b/fuzz/corpus/png_embed/tm3n3p02.png new file mode 100644 index 000000000..fb3ef1d0c Binary files /dev/null and b/fuzz/corpus/png_embed/tm3n3p02.png differ diff --git a/fuzz/corpus/png_embed/tp0n0g08.png b/fuzz/corpus/png_embed/tp0n0g08.png new file mode 100644 index 000000000..333465fcd Binary files /dev/null and b/fuzz/corpus/png_embed/tp0n0g08.png differ diff --git a/fuzz/corpus/png_embed/tp0n2c08.png b/fuzz/corpus/png_embed/tp0n2c08.png new file mode 100644 index 000000000..fc6e42cb4 Binary files /dev/null and b/fuzz/corpus/png_embed/tp0n2c08.png differ diff --git a/fuzz/corpus/png_embed/tp0n3p08.png b/fuzz/corpus/png_embed/tp0n3p08.png new file mode 100644 index 000000000..69a69e587 Binary files /dev/null and b/fuzz/corpus/png_embed/tp0n3p08.png differ diff --git a/fuzz/corpus/png_embed/tp1n3p08.png b/fuzz/corpus/png_embed/tp1n3p08.png new file mode 100644 index 000000000..a6c9f35a8 Binary files /dev/null and b/fuzz/corpus/png_embed/tp1n3p08.png differ diff --git a/fuzz/corpus/png_embed/z00n2c08.png b/fuzz/corpus/png_embed/z00n2c08.png new file mode 100644 index 000000000..7669eb838 Binary files /dev/null and b/fuzz/corpus/png_embed/z00n2c08.png differ diff --git a/fuzz/corpus/png_embed/z03n2c08.png b/fuzz/corpus/png_embed/z03n2c08.png new file mode 100644 index 000000000..bfb10de8d Binary files /dev/null and b/fuzz/corpus/png_embed/z03n2c08.png differ diff --git a/fuzz/corpus/png_embed/z06n2c08.png b/fuzz/corpus/png_embed/z06n2c08.png new file mode 100644 index 000000000..b90ebc10f Binary files /dev/null and b/fuzz/corpus/png_embed/z06n2c08.png differ diff --git a/fuzz/corpus/png_embed/z09n2c08.png b/fuzz/corpus/png_embed/z09n2c08.png new file mode 100644 index 000000000..5f191a78e Binary files /dev/null and b/fuzz/corpus/png_embed/z09n2c08.png differ diff --git a/fuzz/corpus/stream_decode/ascii85_test.bin b/fuzz/corpus/stream_decode/ascii85_test.bin new file mode 100644 index 000000000..7dfec7fc0 --- /dev/null +++ b/fuzz/corpus/stream_decode/ascii85_test.bin @@ -0,0 +1 @@ +Gb"0E\! diff --git a/fuzz/corpus/stream_decode/asciihex_hello.bin b/fuzz/corpus/stream_decode/asciihex_hello.bin new file mode 100644 index 000000000..3662139ca --- /dev/null +++ b/fuzz/corpus/stream_decode/asciihex_hello.bin @@ -0,0 +1 @@ +48656C6C6F> diff --git a/fuzz/corpus/stream_decode/flate_foo.bin b/fuzz/corpus/stream_decode/flate_foo.bin new file mode 100644 index 000000000..41140dd66 Binary files /dev/null and b/fuzz/corpus/stream_decode/flate_foo.bin differ diff --git a/fuzz/corpus/stream_decode/lzw_minimal.bin b/fuzz/corpus/stream_decode/lzw_minimal.bin new file mode 100644 index 000000000..2b50aac0d --- /dev/null +++ b/fuzz/corpus/stream_decode/lzw_minimal.bin @@ -0,0 +1 @@ +€€€€€ diff --git a/fuzz/corpus/stream_decode/runlength_test.bin b/fuzz/corpus/stream_decode/runlength_test.bin new file mode 100644 index 000000000..20237044e --- /dev/null +++ b/fuzz/corpus/stream_decode/runlength_test.bin @@ -0,0 +1 @@ +Hello diff --git a/fuzz/jpeg.dict b/fuzz/jpeg.dict new file mode 100644 index 000000000..18d0f38cd --- /dev/null +++ b/fuzz/jpeg.dict @@ -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" diff --git a/fuzz/jpeg_embed.fuzz.ts b/fuzz/jpeg_embed.fuzz.ts new file mode 100644 index 000000000..ea8e46abd --- /dev/null +++ b/fuzz/jpeg_embed.fuzz.ts @@ -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 { + // 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 + } +} diff --git a/fuzz/jpeg_embed.options b/fuzz/jpeg_embed.options new file mode 100644 index 000000000..a8a52e847 --- /dev/null +++ b/fuzz/jpeg_embed.options @@ -0,0 +1,3 @@ +[libfuzzer] +max_len = 524288 +timeout = 30 diff --git a/fuzz/object_parser.fuzz.ts b/fuzz/object_parser.fuzz.ts new file mode 100644 index 000000000..c550dcfea --- /dev/null +++ b/fuzz/object_parser.fuzz.ts @@ -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 { + // 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 + } +} diff --git a/fuzz/object_parser.options b/fuzz/object_parser.options new file mode 100644 index 000000000..4821a7059 --- /dev/null +++ b/fuzz/object_parser.options @@ -0,0 +1,3 @@ +[libfuzzer] +max_len = 262144 +timeout = 30 diff --git a/fuzz/page_embed.fuzz.ts b/fuzz/page_embed.fuzz.ts new file mode 100644 index 000000000..dc305a10c --- /dev/null +++ b/fuzz/page_embed.fuzz.ts @@ -0,0 +1,85 @@ +// 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 PDF page embedding (embedPdf/embedPage). + * Targets: page content stream processing, bounding box calculation, transformation matrices. + */ + +import PDFDocument from '../src/api/PDFDocument'; + +export async function fuzz(data: Buffer): Promise { + // Skip empty or too large inputs (1MB matches page_embed.options max_len) + if (data.length === 0 || data.length > 1024 * 1024) { + return; + } + + try { + // Try to load the input as a PDF + const srcDoc = await PDFDocument.load(data, { + ignoreEncryption: true, + throwOnInvalidObject: false, + updateMetadata: false, + }); + + const pageCount = srcDoc.getPageCount(); + if (pageCount === 0) { + return; + } + + // Create a new document and try to embed pages + const destDoc = await PDFDocument.create(); + + // Try to embed first page with various bounding boxes + const srcPage = srcDoc.getPage(0); + const { width, height } = srcPage.getSize(); + + // Embed without clipping + try { + await destDoc.embedPage(srcPage); + } catch (e) { /* embedding may fail */ } + + // Embed with bounding box + try { + await destDoc.embedPage(srcPage, { + left: 0, + bottom: 0, + right: Math.min(width, 100), + top: Math.min(height, 100), + }); + } catch (e) { /* embedding may fail */ } + + // Embed with transformation matrix + try { + await destDoc.embedPage(srcPage, undefined, [1, 0, 0, 1, 10, 10]); + } catch (e) { /* embedding may fail */ } + + // Try to copy pages + try { + const indices = []; + for (let i = 0; i < Math.min(pageCount, 3); i++) { + indices.push(i); + } + await destDoc.copyPages(srcDoc, indices); + } catch (e) { /* copying may fail */ } + + // Try to save + try { + await destDoc.save({ addDefaultPage: true }); + } catch (e) { /* save may fail */ } + + } catch (e) { + // Expected for malformed PDF data + } +} diff --git a/fuzz/page_embed.options b/fuzz/page_embed.options new file mode 100644 index 000000000..1bd7b09a5 --- /dev/null +++ b/fuzz/page_embed.options @@ -0,0 +1,4 @@ +[libfuzzer] +max_len = 1048576 +timeout = 60 +rss_limit_mb = 2048 diff --git a/fuzz/pdf.dict b/fuzz/pdf.dict new file mode 100644 index 000000000..ff77e85b3 --- /dev/null +++ b/fuzz/pdf.dict @@ -0,0 +1,189 @@ +# PDF dictionary for fuzzing +# PDF header +"%PDF-1.0" +"%PDF-1.1" +"%PDF-1.2" +"%PDF-1.3" +"%PDF-1.4" +"%PDF-1.5" +"%PDF-1.6" +"%PDF-1.7" +"%PDF-2.0" + +# PDF keywords +"obj" +"endobj" +"stream" +"endstream" +"xref" +"trailer" +"startxref" +"%%EOF" + +# Object types +"/Type" +"/Catalog" +"/Pages" +"/Page" +"/Font" +"/XObject" +"/Image" +"/Form" +"/Annot" +"/Acroform" + +# Common PDF names +"/Root" +"/Info" +"/Size" +"/Prev" +"/ID" +"/Encrypt" +"/Filter" +"/Length" +"/Parent" +"/Kids" +"/Count" +"/MediaBox" +"/Resources" +"/Contents" +"/Subtype" + +# Filter types +"/FlateDecode" +"/DCTDecode" +"/ASCIIHexDecode" +"/ASCII85Decode" +"/LZWDecode" +"/RunLengthDecode" +"/CCITTFaxDecode" +"/JBIG2Decode" +"/JPXDecode" +"/Crypt" + +# Font related +"/BaseFont" +"/Encoding" +"/FontDescriptor" +"/Widths" +"/ToUnicode" +"/CIDFont" +"/DescendantFonts" +"/FontFile" +"/FontFile2" +"/FontFile3" + +# Image related +"/Width" +"/Height" +"/BitsPerComponent" +"/ColorSpace" +"/DeviceRGB" +"/DeviceGray" +"/DeviceCMYK" +"/Indexed" +"/ICCBased" +"/Mask" +"/SMask" + +# Form/Annotation related +"/Fields" +"/T" +"/V" +"/FT" +"/Tx" +"/Btn" +"/Ch" +"/Sig" +"/Rect" +"/AP" +"/N" +"/R" +"/D" +"/DA" +"/DR" +"/NeedAppearances" +"/SigFlags" +"/XFA" + +# Boolean values +"true" +"false" + +# Null +"null" + +# Reference format +" 0 R" +" 0 obj" + +# Array/Dict delimiters +"[" +"]" +"<<" +">>" + +# String delimiters +"(" +")" +"<" +">" + +# Hex escapes for special characters +"\x00" +"\x0a" +"\x0d" +"\x09" +"\x20" +"\x5c" +"\x28" +"\x29" + +# XRef stream specific +"/W" +"/Index" +"/Prev" + +# Object stream specific +"/N" +"/First" +"/ObjStm" + +# Page specific +"/CropBox" +"/BleedBox" +"/TrimBox" +"/ArtBox" +"/Rotate" +"/UserUnit" + +# Content stream operators +"BT" +"ET" +"Tf" +"Td" +"Tj" +"TJ" +"cm" +"q" +"Q" +"re" +"f" +"S" +"Do" + +# Numbers and references +"0 0 R" +"1 0 R" +"0.0" +"-1" +"999999999" + +# Edge cases +"//" +"<<>>" +"[]" +"()" +"<>" +"null null" +"true false" diff --git a/fuzz/pdf_form.fuzz.ts b/fuzz/pdf_form.fuzz.ts new file mode 100644 index 000000000..73cab2d41 --- /dev/null +++ b/fuzz/pdf_form.fuzz.ts @@ -0,0 +1,84 @@ +// 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'; +import PDFTextField from '../src/api/form/PDFTextField'; +import PDFCheckBox from '../src/api/form/PDFCheckBox'; +import PDFRadioGroup from '../src/api/form/PDFRadioGroup'; +import PDFDropdown from '../src/api/form/PDFDropdown'; +import PDFOptionList from '../src/api/form/PDFOptionList'; +import PDFButton from '../src/api/form/PDFButton'; +import PDFSignature from '../src/api/form/PDFSignature'; + +export async function fuzz(data: Buffer): Promise { + // Skip empty or too large inputs (1MB matches pdf_form.options max_len) + if (data.length === 0 || data.length > 1024 * 1024) { + return; + } + + try { + const pdfDoc = await PDFDocument.load(data, { + ignoreEncryption: true, + throwOnInvalidObject: false, + updateMetadata: false, + }); + + // Access the form + const form = pdfDoc.getForm(); + + // Get all fields + const fields = form.getFields(); + + // Iterate through fields using instanceof for type-specific logic + for (const field of fields) { + field.getName(); + + if (field instanceof PDFTextField) { + field.getText(); + field.setText('test'); + field.getMaxLength(); + field.isMultiline(); + field.isPassword(); + field.isFileSelector(); + field.isRichFormatted(); + } else if (field instanceof PDFCheckBox) { + field.isChecked(); + field.check(); + field.uncheck(); + } else if (field instanceof PDFRadioGroup) { + field.getOptions(); + field.getSelected(); + } else if (field instanceof PDFDropdown) { + field.getOptions(); + field.getSelected(); + field.isEditable(); + field.isMultiselect(); + } else if (field instanceof PDFOptionList) { + field.getOptions(); + field.getSelected(); + field.isMultiselect(); + } else if (field instanceof PDFButton) { + field.isReadOnly(); + } else if (field instanceof PDFSignature) { + field.isReadOnly(); + } + } + + // Try to flatten the form + form.flatten(); + + } catch (e) { + // Expected for malformed PDF data + } +} diff --git a/fuzz/pdf_form.options b/fuzz/pdf_form.options new file mode 100644 index 000000000..cfaf21dd1 --- /dev/null +++ b/fuzz/pdf_form.options @@ -0,0 +1,4 @@ +[libfuzzer] +max_len = 1048576 +timeout = 30 +rss_limit_mb = 1024 diff --git a/fuzz/pdf_modify.fuzz.ts b/fuzz/pdf_modify.fuzz.ts new file mode 100644 index 000000000..4724da793 --- /dev/null +++ b/fuzz/pdf_modify.fuzz.ts @@ -0,0 +1,81 @@ +// 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'; +import { StandardFonts } from '../src/api/StandardFonts'; +import { rgb } from '../src/api/colors'; + +export async function fuzz(data: Buffer): Promise { + // Skip empty or too large inputs + if (data.length === 0 || data.length > 1024 * 1024) { + return; + } + + try { + // Load the PDF + const pdfDoc = await PDFDocument.load(data, { + ignoreEncryption: true, + throwOnInvalidObject: false, + updateMetadata: false, + }); + + const pages = pdfDoc.getPages(); + if (pages.length === 0) { + return; + } + + // Try to modify the first page + const firstPage = pages[0]; + const { width, height } = firstPage.getSize(); + + // Embed a standard font + const font = await pdfDoc.embedFont(StandardFonts.Helvetica); + + // Draw text on the page + firstPage.drawText('Fuzz Test', { + x: Math.min(50, width / 2), + y: Math.min(50, height / 2), + size: 12, + font: font, + color: rgb(0, 0, 0), + }); + + // Draw a rectangle + firstPage.drawRectangle({ + x: 0, + y: 0, + width: Math.min(100, width), + height: Math.min(100, height), + borderColor: rgb(0, 0, 0), + borderWidth: 1, + }); + + // Try to save (exercises the writer) + const savedBytes = await pdfDoc.save({ + useObjectStreams: false, + addDefaultPage: false, + updateFieldAppearances: false, + }); + + // Round-trip validation: ensure the saved PDF can be loaded back + await PDFDocument.load(savedBytes, { + ignoreEncryption: true, + throwOnInvalidObject: false, + updateMetadata: false, + }); + + } catch (e) { + // Expected for malformed PDF data + } +} diff --git a/fuzz/pdf_modify.options b/fuzz/pdf_modify.options new file mode 100644 index 000000000..1bd7b09a5 --- /dev/null +++ b/fuzz/pdf_modify.options @@ -0,0 +1,4 @@ +[libfuzzer] +max_len = 1048576 +timeout = 60 +rss_limit_mb = 2048 diff --git a/fuzz/pdf_parser.fuzz.ts b/fuzz/pdf_parser.fuzz.ts new file mode 100644 index 000000000..a518de650 --- /dev/null +++ b/fuzz/pdf_parser.fuzz.ts @@ -0,0 +1,67 @@ +// 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 { + // Skip empty or too large inputs + if (data.length === 0 || data.length > 1024 * 1024) { + return; + } + + try { + const pdfDoc = await PDFDocument.load(data, { + ignoreEncryption: true, + throwOnInvalidObject: false, + updateMetadata: false, + }); + + // Exercise additional parsing functionality + pdfDoc.getPageCount(); + + const pages = pdfDoc.getPages(); + for (let i = 0; i < Math.min(pages.length, 5); i++) { + const page = pages[i]; + page.getSize(); + page.getWidth(); + page.getHeight(); + page.getRotation(); + } + + // Try to get document metadata + try { + pdfDoc.getTitle(); + pdfDoc.getAuthor(); + pdfDoc.getSubject(); + pdfDoc.getCreator(); + pdfDoc.getProducer(); + pdfDoc.getCreationDate(); + pdfDoc.getModificationDate(); + } catch (e) { + // Metadata parsing errors are expected for malformed PDFs + } + + // Try to access form if present + try { + const form = pdfDoc.getForm(); + form.getFields(); + } catch (e) { + // Form access errors are expected for PDFs without forms + } + + } catch (e) { + // Expected for malformed PDF data + // Parsing errors should be caught, not crash the fuzzer + } +} diff --git a/fuzz/pdf_parser.options b/fuzz/pdf_parser.options new file mode 100644 index 000000000..700afbf45 --- /dev/null +++ b/fuzz/pdf_parser.options @@ -0,0 +1,3 @@ +[libfuzzer] +max_len = 1048576 +timeout = 30 diff --git a/fuzz/pdf_string.fuzz.ts b/fuzz/pdf_string.fuzz.ts new file mode 100644 index 000000000..0d79c6ef2 --- /dev/null +++ b/fuzz/pdf_string.fuzz.ts @@ -0,0 +1,84 @@ +// 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 PDFString and PDFHexString parsing. + * Targets: escape sequences (\n, \r, \t, octal), UTF-16 BOM, date parsing. + */ + +import PDFString from '../src/core/objects/PDFString'; +import PDFHexString from '../src/core/objects/PDFHexString'; + +export async function fuzz(data: Buffer): Promise { + // Skip empty or too large inputs + if (data.length === 0 || data.length > 64 * 1024) { + return; + } + + // Use first byte to determine test type + const testType = data[0] % 4; + const testData = data.slice(1); + + try { + switch (testType) { + case 0: + // Test PDFString.of (literal string) + { + const str = PDFString.of(testData.toString('binary')); + str.decodeText(); + str.decodeDate(); + str.asString(); + str.sizeInBytes(); + } + break; + + case 1: + // Test PDFHexString.of with raw fuzz data as potential hex characters + // This tests parsing of arbitrary characters (valid/invalid hex) + { + const hexStr = PDFHexString.of(testData.toString('latin1')); + hexStr.decodeText(); + hexStr.decodeDate(); + hexStr.asString(); + hexStr.sizeInBytes(); + } + break; + + case 2: + // Test PDFHexString.fromText with arbitrary text + { + const hexStr = PDFHexString.fromText(testData.toString('utf8')); + hexStr.decodeText(); + hexStr.asString(); + } + break; + + case 3: + // Test PDFString with potential escape sequences + { + // Build a string with escape sequences + const escaped = testData.toString('binary') + .replace(/\\/g, '\\\\') + .replace(/\(/g, '\\(') + .replace(/\)/g, '\\)'); + const str = PDFString.of(escaped); + str.decodeText(); + str.asString(); + } + break; + } + } catch (e) { + // Expected for malformed strings + } +} diff --git a/fuzz/pdf_string.options b/fuzz/pdf_string.options new file mode 100644 index 000000000..2192aae36 --- /dev/null +++ b/fuzz/pdf_string.options @@ -0,0 +1,3 @@ +[libfuzzer] +max_len = 65536 +timeout = 10 diff --git a/fuzz/png.dict b/fuzz/png.dict new file mode 100644 index 000000000..6b7476895 --- /dev/null +++ b/fuzz/png.dict @@ -0,0 +1,79 @@ +# PNG dictionary for fuzzing +# PNG signature +"\x89PNG\x0d\x0a\x1a\x0a" + +# Critical chunks +"IHDR" +"PLTE" +"IDAT" +"IEND" + +# Ancillary chunks +"cHRM" +"gAMA" +"iCCP" +"sBIT" +"sRGB" +"bKGD" +"hIST" +"tRNS" +"pHYs" +"sPLT" +"tIME" +"iTXt" +"tEXt" +"zTXt" + +# Common chunk lengths +"\x00\x00\x00\x00" +"\x00\x00\x00\x01" +"\x00\x00\x00\x04" +"\x00\x00\x00\x08" +"\x00\x00\x00\x0d" +"\x00\x00\x00\x10" +"\x00\x00\x00\x20" + +# IHDR chunk structure +"\x00\x00\x00\x0dIHDR" + +# Color types +"\x00" +"\x02" +"\x03" +"\x04" +"\x06" + +# Bit depths +"\x01" +"\x02" +"\x04" +"\x08" +"\x10" + +# Compression method +"\x00" + +# Filter method +"\x00" + +# Interlace method +"\x00" +"\x01" + +# Common dimensions (big endian) +"\x00\x00\x00\x01" +"\x00\x00\x00\x10" +"\x00\x00\x00\x40" +"\x00\x00\x00\x64" +"\x00\x00\x01\x00" + +# IEND chunk +"\x00\x00\x00\x00IEND\xaeB`\x82" + +# zlib header +"\x78\x9c" +"\x78\x01" +"\x78\xda" + +# Adler-32 checksum placeholder +"\x00\x00\x00\x01" diff --git a/fuzz/png_embed.fuzz.ts b/fuzz/png_embed.fuzz.ts new file mode 100644 index 000000000..bc218c5d7 --- /dev/null +++ b/fuzz/png_embed.fuzz.ts @@ -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 { + // Skip empty or too large inputs + if (data.length === 0 || data.length > 512 * 1024) { + return; + } + + try { + const pdfDoc = await PDFDocument.create(); + const pngImage = await pdfDoc.embedPng(data); + + // Exercise the embedded image + pngImage.width; + pngImage.height; + pngImage.scale(0.5); + pngImage.scaleToFit(100, 100); + + // Draw the image on a page + const page = pdfDoc.addPage(); + page.drawImage(pngImage, { + x: 0, + y: 0, + width: Math.min(pngImage.width, 100), + height: Math.min(pngImage.height, 100), + }); + + } catch (e) { + // Expected for malformed PNG data + } +} diff --git a/fuzz/png_embed.options b/fuzz/png_embed.options new file mode 100644 index 000000000..a8a52e847 --- /dev/null +++ b/fuzz/png_embed.options @@ -0,0 +1,3 @@ +[libfuzzer] +max_len = 524288 +timeout = 30 diff --git a/fuzz/stream_decode.fuzz.ts b/fuzz/stream_decode.fuzz.ts new file mode 100644 index 000000000..ea6a2f747 --- /dev/null +++ b/fuzz/stream_decode.fuzz.ts @@ -0,0 +1,69 @@ +// 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 PDF stream decoders (FlateStream, LZWStream, Ascii85, AsciiHex, RunLength) + * These are critical for decompression bomb and parsing vulnerabilities. + */ + +import { decodePDFRawStream } from '../src/core/streams/decode'; +import PDFRawStream from '../src/core/objects/PDFRawStream'; +import PDFDict from '../src/core/objects/PDFDict'; +import PDFName from '../src/core/objects/PDFName'; +import PDFNumber from '../src/core/objects/PDFNumber'; +import PDFContext from '../src/core/PDFContext'; + +const FILTERS = [ + 'FlateDecode', + 'LZWDecode', + 'ASCII85Decode', + 'ASCIIHexDecode', + 'RunLengthDecode', +]; + +export async function fuzz(data: Buffer): Promise { + // Skip empty or too large inputs + if (data.length < 2 || data.length > 512 * 1024) { + return; + } + + // Use first byte to select filter type + const filterIndex = data[0] % FILTERS.length; + const filterName = FILTERS[filterIndex]; + const streamData = data.slice(1); + + try { + const context = PDFContext.create(); + + // Create a dict with the filter + const dict = PDFDict.withContext(context); + dict.set(PDFName.of('Filter'), PDFName.of(filterName)); + dict.set(PDFName.of('Length'), PDFNumber.of(streamData.length)); + + // Create raw stream + const rawStream = PDFRawStream.of(dict, streamData); + + // Decode the stream - this exercises the stream decoders + // decodePDFRawStream returns a wrapped stream, decode() triggers actual decompression + const stream = decodePDFRawStream(rawStream); + + // Safely call decode - stream is always defined but guard against edge cases + if (stream && typeof stream.decode === 'function') { + stream.decode(); + } + + } catch (e) { + // Expected for malformed compressed data + } +} diff --git a/fuzz/stream_decode.options b/fuzz/stream_decode.options new file mode 100644 index 000000000..855edbe4e --- /dev/null +++ b/fuzz/stream_decode.options @@ -0,0 +1,4 @@ +[libfuzzer] +max_len = 524288 +timeout = 60 +rss_limit_mb = 2048 diff --git a/fuzz/xref_stream.fuzz.ts b/fuzz/xref_stream.fuzz.ts new file mode 100644 index 000000000..c722aec8e --- /dev/null +++ b/fuzz/xref_stream.fuzz.ts @@ -0,0 +1,77 @@ +// 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 XRef stream parsing (modern PDF cross-reference format). + * Targets: field width parsing, binary xref entries, subsection handling. + */ + +import PDFDocument from '../src/api/PDFDocument'; + +export async function fuzz(data: Buffer): Promise { + // Skip empty or too large inputs + if (data.length < 10 || data.length > 256 * 1024) { + return; + } + + // Build a PDF with XRef stream instead of traditional xref table + // Use fuzzer data to construct the xref stream content + + // Minimal PDF 1.5+ with XRef stream + // Build in parts to calculate offset correctly + const pdfHeader = `%PDF-1.5 +%\x80\x80\x80\x80 +1 0 obj +<< /Type /Catalog /Pages 2 0 R >> +endobj +2 0 obj +<< /Type /Pages /Kids [] /Count 0 >> +endobj +`; + + // XRef stream object starts here - this is what startxref should point to + const xrefOffset = Buffer.from(pdfHeader).length; + + const xrefObj = `3 0 obj +<< /Type /XRef /Size 4 /W [1 2 1] /Root 1 0 R /Length ${data.length} >> +stream +`; + + const pdfPrefix = pdfHeader + xrefObj; + + const pdfSuffix = ` +endstream +endobj +startxref +`; + + // Build PDF with fuzzed xref stream data + const pdfData = Buffer.concat([ + Buffer.from(pdfPrefix), + data, + Buffer.from(pdfSuffix), + Buffer.from(xrefOffset.toString()), + Buffer.from('\n%%EOF'), + ]); + + try { + await PDFDocument.load(pdfData, { + ignoreEncryption: true, + throwOnInvalidObject: false, + updateMetadata: false, + }); + } catch (e) { + // Expected for malformed xref data + } +} diff --git a/fuzz/xref_stream.options b/fuzz/xref_stream.options new file mode 100644 index 000000000..4821a7059 --- /dev/null +++ b/fuzz/xref_stream.options @@ -0,0 +1,3 @@ +[libfuzzer] +max_len = 262144 +timeout = 30 diff --git a/oss-fuzz/Dockerfile b/oss-fuzz/Dockerfile new file mode 100644 index 000000000..5de4f075a --- /dev/null +++ b/oss-fuzz/Dockerfile @@ -0,0 +1,25 @@ +# 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. +# +################################################################################ + +FROM gcr.io/oss-fuzz-base/base-builder-javascript + +RUN apt-get update && apt-get install -y make autoconf automake libtool + +# Clone pdf-lib +RUN git clone --depth 1 https://github.com/Hopding/pdf-lib.git pdf-lib + +WORKDIR pdf-lib +COPY build.sh $SRC/ diff --git a/oss-fuzz/build.sh b/oss-fuzz/build.sh new file mode 100644 index 000000000..694dda624 --- /dev/null +++ b/oss-fuzz/build.sh @@ -0,0 +1,70 @@ +#!/bin/bash -eu +# 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. +# +################################################################################ + +# Install dependencies +npm install + +# Install fuzzing dependencies (not in devDependencies to avoid TS version conflicts) +npm install --no-save @jazzer.js/core esbuild + +# Build each fuzzer using esbuild (bundles TypeScript and resolves path aliases) +FUZZERS="pdf_parser pdf_modify pdf_form jpeg_embed png_embed stream_decode object_parser pdf_string xref_stream page_embed" + +for fuzzer in $FUZZERS; do + echo "Building ${fuzzer} fuzzer..." + npx esbuild fuzz/${fuzzer}.fuzz.ts \ + --bundle \ + --platform=node \ + --target=node18 \ + --outfile=fuzz/${fuzzer}.fuzz.js \ + --format=cjs \ + --external:@jazzer.js/core +done + +# Compile fuzzers for OSS-Fuzz +for fuzzer in $FUZZERS; do + compile_javascript_fuzzer pdf-lib fuzz/${fuzzer}.fuzz --sync +done + +# Copy dictionaries +cp fuzz/pdf.dict $OUT/pdf_parser.dict +cp fuzz/pdf.dict $OUT/pdf_modify.dict +cp fuzz/pdf.dict $OUT/pdf_form.dict +cp fuzz/pdf.dict $OUT/object_parser.dict +cp fuzz/pdf.dict $OUT/xref_stream.dict +cp fuzz/pdf.dict $OUT/page_embed.dict +cp fuzz/pdf.dict $OUT/stream_decode.dict +cp fuzz/pdf.dict $OUT/pdf_string.dict +cp fuzz/jpeg.dict $OUT/jpeg_embed.dict +cp fuzz/png.dict $OUT/png_embed.dict + +# Copy options files +cp fuzz/*.options $OUT/ 2>/dev/null || true + +# Create seed corpus zips +zip -j $OUT/pdf_parser_seed_corpus.zip fuzz/corpus/pdf_parser/* 2>/dev/null || true +zip -j $OUT/pdf_modify_seed_corpus.zip fuzz/corpus/pdf_modify/* 2>/dev/null || true +zip -j $OUT/pdf_form_seed_corpus.zip fuzz/corpus/pdf_form/* 2>/dev/null || true +zip -j $OUT/jpeg_embed_seed_corpus.zip fuzz/corpus/jpeg_embed/* 2>/dev/null || true +zip -j $OUT/png_embed_seed_corpus.zip fuzz/corpus/png_embed/* 2>/dev/null || true +zip -j $OUT/object_parser_seed_corpus.zip fuzz/corpus/pdf_parser/* 2>/dev/null || true +zip -j $OUT/xref_stream_seed_corpus.zip fuzz/corpus/pdf_parser/* 2>/dev/null || true +zip -j $OUT/page_embed_seed_corpus.zip fuzz/corpus/pdf_parser/* 2>/dev/null || true +zip -j $OUT/stream_decode_seed_corpus.zip fuzz/corpus/stream_decode/* fuzz/corpus/pdf_parser/* 2>/dev/null || true +zip -j $OUT/pdf_string_seed_corpus.zip fuzz/corpus/pdf_parser/* 2>/dev/null || true + +echo "Build complete!" diff --git a/oss-fuzz/project.yaml b/oss-fuzz/project.yaml new file mode 100644 index 000000000..5e3e9aa56 --- /dev/null +++ b/oss-fuzz/project.yaml @@ -0,0 +1,8 @@ +homepage: "https://github.com/Hopding/pdf-lib" +language: javascript +primary_contact: "andrew.dillon.j@gmail.com" +main_repo: "https://github.com/Hopding/pdf-lib" +fuzzing_engines: + - libfuzzer +sanitizers: + - none