diff --git a/test/fuzz/ccitt_stream.fuzz.js b/test/fuzz/ccitt_stream.fuzz.js new file mode 100644 index 0000000000000..fdd574380e6b0 --- /dev/null +++ b/test/fuzz/ccitt_stream.fuzz.js @@ -0,0 +1,83 @@ +// 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 CCITT fax stream decoding (Group 3 and Group 4). + * Used for fax-encoded images in PDFs. + */ + +const MAX_INPUT_SIZE = 128 * 1024; // 128KB limit + +let CCITTFaxDecoder = null; + +async function init() { + if (CCITTFaxDecoder) return; + const ccittModule = await import("../../build/lib-legacy/core/ccitt.js"); + CCITTFaxDecoder = ccittModule.CCITTFaxDecoder; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + + if (data.length < 4 || data.length > MAX_INPUT_SIZE) { + return; + } + + // Use first 4 bytes to derive decoder parameters + const params = { + K: (data[0] % 3) - 1, // -1, 0, or 1 + EndOfLine: !!(data[1] & 0x01), + EncodedByteAlign: !!(data[1] & 0x02), + Columns: ((data[2] << 8) | data[3]) % 4096 + 1, + Rows: 0, + EndOfBlock: !!(data[1] & 0x04), + BlackIs1: !!(data[1] & 0x08), + }; + + try { + const source = { + next: (function() { + let pos = 4; + return function() { + if (pos >= data.length) { + return -1; + } + return data[pos++]; + }; + })() + }; + + const decoder = new CCITTFaxDecoder(source, params); + + // Try to decode some data + let bytesRead = 0; + const maxBytes = 1024 * 1024; // 1MB output limit + let byte; + while ((byte = decoder.readNextChar()) !== -1 && bytesRead < maxBytes) { + bytesRead++; + } + } catch (e) { + // Expected exceptions for malformed CCITT data + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; + } + } +}; diff --git a/test/fuzz/cff_parser.fuzz.js b/test/fuzz/cff_parser.fuzz.js new file mode 100644 index 0000000000000..7c3e2c4671b4c --- /dev/null +++ b/test/fuzz/cff_parser.fuzz.js @@ -0,0 +1,78 @@ +// 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 CFF (Compact Font Format) parsing. + * CFF fonts are complex with charstring bytecode interpretation. + */ + +const MAX_INPUT_SIZE = 256 * 1024; // 256KB limit + +let CFFParser = null; + +async function init() { + if (CFFParser) return; + const cffModule = await import("../../build/lib-legacy/core/cff_parser.js"); + CFFParser = cffModule.CFFParser; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + + if (data.length < 4 || data.length > MAX_INPUT_SIZE) { + return; + } + + try { + const bytes = new Uint8Array(data); + const parser = new CFFParser( + { + getBytes: () => bytes, + pos: 0, + length: bytes.length, + }, + {}, // properties + true // isCIDFont - try both modes + ); + + const cff = parser.parse(); + + // Try to access font data + if (cff) { + // Access charstrings if available + if (cff.charStrings) { + const count = Math.min(cff.charStrings.count || 0, 10); + for (let i = 0; i < count; i++) { + try { + cff.charStrings.get(i); + } catch (e) { + // Individual charstring errors expected + } + } + } + } + } catch (e) { + // Expected exceptions for malformed CFF data + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; + } + } +}; diff --git a/test/fuzz/cmap_parser.fuzz.js b/test/fuzz/cmap_parser.fuzz.js new file mode 100644 index 0000000000000..8838b17fe6d69 --- /dev/null +++ b/test/fuzz/cmap_parser.fuzz.js @@ -0,0 +1,68 @@ +// 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 CMap (Character Map) parsing. + * CMaps define character code to glyph mappings. + */ + +const MAX_INPUT_SIZE = 128 * 1024; // 128KB limit + +let CMapFactory = null; + +async function init() { + if (CMapFactory) return; + const cmapModule = await import("../../build/lib-legacy/core/cmap.js"); + CMapFactory = cmapModule.CMapFactory; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + + if (data.length === 0 || data.length > MAX_INPUT_SIZE) { + return; + } + + try { + // Create a minimal fetch function that returns our data + const fetchBuiltInCMap = async () => ({ + cMapData: new Uint8Array(data), + compressionType: 0, + }); + + const cmap = await CMapFactory.create({ + encoding: { name: "Identity-H" }, + fetchBuiltInCMap, + useCMap: null, + }); + + // Try to use the cmap + if (cmap) { + cmap.lookup(0x0041); + cmap.lookup(0x3000); + } + } catch (e) { + // Expected exceptions for malformed CMap data + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; + } + } +}; diff --git a/test/fuzz/colorspace.fuzz.js b/test/fuzz/colorspace.fuzz.js new file mode 100644 index 0000000000000..4e7367b0f28a5 --- /dev/null +++ b/test/fuzz/colorspace.fuzz.js @@ -0,0 +1,80 @@ +// 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 Colorspace parsing including ICC profiles. + */ + +const MAX_INPUT_SIZE = 128 * 1024; // 128KB limit + +let ColorSpace = null; +let Name = null; +let Dict = null; + +async function init() { + if (ColorSpace) return; + const colorspaceModule = await import("../../build/lib-legacy/core/colorspace.js"); + const primitivesModule = await import("../../build/lib-legacy/core/primitives.js"); + ColorSpace = colorspaceModule.ColorSpace; + Name = primitivesModule.Name; + Dict = primitivesModule.Dict; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + + if (data.length < 4 || data.length > MAX_INPUT_SIZE) { + return; + } + + try { + // Create a mock XRef and resources + const xref = { + fetch: () => null, + fetchIfRef: (obj) => obj, + }; + const resources = new Dict(xref); + + // Construct colorspace name from first byte + const csTypes = [ + "DeviceGray", "DeviceRGB", "DeviceCMYK", + "CalGray", "CalRGB", "Lab", + "ICCBased", "Indexed", "Pattern", "Separation" + ]; + const csType = csTypes[data[0] % csTypes.length]; + const csName = Name.get(csType); + + ColorSpace.parse({ + cs: csName, + xref, + resources, + pdfFunctionFactory: { + create: () => ({ parse: () => null }), + }, + localColorSpaceCache: new Map(), + }); + } catch (e) { + // Expected exceptions for malformed colorspace data + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; + } + } +}; diff --git a/test/fuzz/corpus/ccitt_stream/ccitt_EndOfBlock_false.pdf b/test/fuzz/corpus/ccitt_stream/ccitt_EndOfBlock_false.pdf new file mode 100644 index 0000000000000..d3aa89aa26fec Binary files /dev/null and b/test/fuzz/corpus/ccitt_stream/ccitt_EndOfBlock_false.pdf differ diff --git a/test/fuzz/corpus/ccitt_stream/minimal_g3.ccitt b/test/fuzz/corpus/ccitt_stream/minimal_g3.ccitt new file mode 100644 index 0000000000000..d86cdd70d6a7c Binary files /dev/null and b/test/fuzz/corpus/ccitt_stream/minimal_g3.ccitt differ diff --git a/test/fuzz/corpus/cff_parser/minimal.cff b/test/fuzz/corpus/cff_parser/minimal.cff new file mode 100644 index 0000000000000..8e25d8d0f1b1d Binary files /dev/null and b/test/fuzz/corpus/cff_parser/minimal.cff differ diff --git a/test/fuzz/corpus/cff_parser/minimal_cff.bin b/test/fuzz/corpus/cff_parser/minimal_cff.bin new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/test/fuzz/corpus/cmap_parser/identity.cmap b/test/fuzz/corpus/cmap_parser/identity.cmap new file mode 100644 index 0000000000000..b170a39d98d80 --- /dev/null +++ b/test/fuzz/corpus/cmap_parser/identity.cmap @@ -0,0 +1,14 @@ +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> def +/CMapName /Identity-H def +/CMapType 1 def +1 begincodespacerange +<0000> +endcodespacerange +endcmap +CMapName currentdict /CMap defineresource pop +end +end diff --git a/test/fuzz/corpus/colorspace/calrgb.pdf b/test/fuzz/corpus/colorspace/calrgb.pdf new file mode 100644 index 0000000000000..420bf3c0a4f4c Binary files /dev/null and b/test/fuzz/corpus/colorspace/calrgb.pdf differ diff --git a/test/fuzz/corpus/colorspace/cmykjpeg.pdf b/test/fuzz/corpus/colorspace/cmykjpeg.pdf new file mode 100644 index 0000000000000..8e3b85a06118f Binary files /dev/null and b/test/fuzz/corpus/colorspace/cmykjpeg.pdf differ diff --git a/test/fuzz/corpus/colorspace/colorspace_atan.pdf b/test/fuzz/corpus/colorspace/colorspace_atan.pdf new file mode 100644 index 0000000000000..897495b8f5d43 Binary files /dev/null and b/test/fuzz/corpus/colorspace/colorspace_atan.pdf differ diff --git a/test/fuzz/corpus/colorspace/colorspace_cos.pdf b/test/fuzz/corpus/colorspace/colorspace_cos.pdf new file mode 100644 index 0000000000000..08cd1fb72cd74 Binary files /dev/null and b/test/fuzz/corpus/colorspace/colorspace_cos.pdf differ diff --git a/test/fuzz/corpus/colorspace/colorspace_sin.pdf b/test/fuzz/corpus/colorspace/colorspace_sin.pdf new file mode 100644 index 0000000000000..5b56008d31318 Binary files /dev/null and b/test/fuzz/corpus/colorspace/colorspace_sin.pdf differ diff --git a/test/fuzz/corpus/crypto/sample1.bin b/test/fuzz/corpus/crypto/sample1.bin new file mode 100644 index 0000000000000..7b252c29eb89d Binary files /dev/null and b/test/fuzz/corpus/crypto/sample1.bin differ diff --git a/test/fuzz/corpus/crypto/sample2.bin b/test/fuzz/corpus/crypto/sample2.bin new file mode 100644 index 0000000000000..853790353554e Binary files /dev/null and b/test/fuzz/corpus/crypto/sample2.bin differ diff --git a/test/fuzz/corpus/flate_stream/empty.z b/test/fuzz/corpus/flate_stream/empty.z new file mode 100644 index 0000000000000..f89cd1a721f48 Binary files /dev/null and b/test/fuzz/corpus/flate_stream/empty.z differ diff --git a/test/fuzz/corpus/flate_stream/hello.z b/test/fuzz/corpus/flate_stream/hello.z new file mode 100644 index 0000000000000..48070753b6434 Binary files /dev/null and b/test/fuzz/corpus/flate_stream/hello.z differ diff --git a/test/fuzz/corpus/flate_stream/raw.deflate b/test/fuzz/corpus/flate_stream/raw.deflate new file mode 100644 index 0000000000000..4a05bda9c9f27 Binary files /dev/null and b/test/fuzz/corpus/flate_stream/raw.deflate differ diff --git a/test/fuzz/corpus/formcalc_parser/complex.fc b/test/fuzz/corpus/formcalc_parser/complex.fc new file mode 100644 index 0000000000000..8818b88422177 --- /dev/null +++ b/test/fuzz/corpus/formcalc_parser/complex.fc @@ -0,0 +1,29 @@ +// Complex FormCalc script +var total = 0 +var count = 0 +var avg = 0 + +func Calculate(a, b, c) + var sum = a + b + c + return sum / 3 +endfunc + +for i = 1 upto 10 step 1 do + total = total + i + count = count + 1 +endfor + +if (count > 0) then + avg = total / count + if (avg > 5) then + avg = Round(avg, 2) + endif +endif + +foreach item in (1, 2, 3, 4, 5) do + total = total + item +endfor + +while (count < 20) do + count = count + 1 +endwhile diff --git a/test/fuzz/corpus/formcalc_parser/functions.fc b/test/fuzz/corpus/formcalc_parser/functions.fc new file mode 100644 index 0000000000000..88b091a11c440 --- /dev/null +++ b/test/fuzz/corpus/formcalc_parser/functions.fc @@ -0,0 +1,7 @@ +func Add(a, b) + return a + b +endfunc + +var result = Add(10, 20) +var text = Concat("Hello ", "World") +var len = Len(text) diff --git a/test/fuzz/corpus/formcalc_parser/simple.fc b/test/fuzz/corpus/formcalc_parser/simple.fc new file mode 100644 index 0000000000000..dada697444751 --- /dev/null +++ b/test/fuzz/corpus/formcalc_parser/simple.fc @@ -0,0 +1,5 @@ +var x = 1 + 2 +var y = x * 3 +if (y > 5) then + y = y - 1 +endif diff --git a/test/fuzz/corpus/jbig2_image/jbig2_symbol_offset.pdf b/test/fuzz/corpus/jbig2_image/jbig2_symbol_offset.pdf new file mode 100644 index 0000000000000..e653b42a7916d Binary files /dev/null and b/test/fuzz/corpus/jbig2_image/jbig2_symbol_offset.pdf differ diff --git a/test/fuzz/corpus/jbig2_image/minimal.jbig2 b/test/fuzz/corpus/jbig2_image/minimal.jbig2 new file mode 100644 index 0000000000000..537e35d078f1e --- /dev/null +++ b/test/fuzz/corpus/jbig2_image/minimal.jbig2 @@ -0,0 +1,2 @@ +�JB2 + diff --git a/test/fuzz/corpus/jpeg_image/jfif_header.jpg b/test/fuzz/corpus/jpeg_image/jfif_header.jpg new file mode 100644 index 0000000000000..0d343780f45d7 Binary files /dev/null and b/test/fuzz/corpus/jpeg_image/jfif_header.jpg differ diff --git a/test/fuzz/corpus/jpeg_image/minimal.jpg b/test/fuzz/corpus/jpeg_image/minimal.jpg new file mode 100644 index 0000000000000..8b4cd3eaa5893 Binary files /dev/null and b/test/fuzz/corpus/jpeg_image/minimal.jpg differ diff --git a/test/fuzz/corpus/jpx_image/jp2k-resetprob.pdf b/test/fuzz/corpus/jpx_image/jp2k-resetprob.pdf new file mode 100644 index 0000000000000..5222158ab5dfe Binary files /dev/null and b/test/fuzz/corpus/jpx_image/jp2k-resetprob.pdf differ diff --git a/test/fuzz/corpus/jpx_image/minimal.jp2 b/test/fuzz/corpus/jpx_image/minimal.jp2 new file mode 100644 index 0000000000000..3cf29f5d59c54 Binary files /dev/null and b/test/fuzz/corpus/jpx_image/minimal.jp2 differ diff --git a/test/fuzz/corpus/lzw_stream/minimal.lzw b/test/fuzz/corpus/lzw_stream/minimal.lzw new file mode 100644 index 0000000000000..68a1086b3a5d1 Binary files /dev/null and b/test/fuzz/corpus/lzw_stream/minimal.lzw differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-as.pdf b/test/fuzz/corpus/pdf_parser/annotation-as.pdf new file mode 100644 index 0000000000000..f03e58a8f0e44 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-as.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-border-styles.pdf b/test/fuzz/corpus/pdf_parser/annotation-border-styles.pdf new file mode 100644 index 0000000000000..0eefa6dd9712d Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-border-styles.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-button-widget.pdf b/test/fuzz/corpus/pdf_parser/annotation-button-widget.pdf new file mode 100644 index 0000000000000..f1fa2394c752f Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-button-widget.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-caret-ink.pdf b/test/fuzz/corpus/pdf_parser/annotation-caret-ink.pdf new file mode 100644 index 0000000000000..6e8679fa585c8 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-caret-ink.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-choice-widget.pdf b/test/fuzz/corpus/pdf_parser/annotation-choice-widget.pdf new file mode 100644 index 0000000000000..b557d9a851f2d Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-choice-widget.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-fileattachment.pdf b/test/fuzz/corpus/pdf_parser/annotation-fileattachment.pdf new file mode 100644 index 0000000000000..c3b60cd7e649e Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-fileattachment.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-freetext.pdf b/test/fuzz/corpus/pdf_parser/annotation-freetext.pdf new file mode 100755 index 0000000000000..771fb9f93287a Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-freetext.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-highlight-without-appearance.pdf b/test/fuzz/corpus/pdf_parser/annotation-highlight-without-appearance.pdf new file mode 100644 index 0000000000000..007493362c34b Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-highlight-without-appearance.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-highlight.pdf b/test/fuzz/corpus/pdf_parser/annotation-highlight.pdf new file mode 100644 index 0000000000000..ab2ef6ec9711d Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-highlight.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-ink-without-appearance.pdf b/test/fuzz/corpus/pdf_parser/annotation-ink-without-appearance.pdf new file mode 100644 index 0000000000000..8b835b1dc83df Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-ink-without-appearance.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-line-without-appearance-empty-Rect.pdf b/test/fuzz/corpus/pdf_parser/annotation-line-without-appearance-empty-Rect.pdf new file mode 100644 index 0000000000000..bfa23b8944868 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-line-without-appearance-empty-Rect.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-line-without-appearance.pdf b/test/fuzz/corpus/pdf_parser/annotation-line-without-appearance.pdf new file mode 100644 index 0000000000000..b85b756716941 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-line-without-appearance.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-line.pdf b/test/fuzz/corpus/pdf_parser/annotation-line.pdf new file mode 100755 index 0000000000000..2a81992e72358 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-line.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-link-text-popup.pdf b/test/fuzz/corpus/pdf_parser/annotation-link-text-popup.pdf new file mode 100644 index 0000000000000..2a840b172905b Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-link-text-popup.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-polyline-polygon-without-appearance.pdf b/test/fuzz/corpus/pdf_parser/annotation-polyline-polygon-without-appearance.pdf new file mode 100644 index 0000000000000..2dc953768d802 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-polyline-polygon-without-appearance.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-polyline-polygon.pdf b/test/fuzz/corpus/pdf_parser/annotation-polyline-polygon.pdf new file mode 100755 index 0000000000000..ec5d05872267b Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-polyline-polygon.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-square-circle-without-appearance.pdf b/test/fuzz/corpus/pdf_parser/annotation-square-circle-without-appearance.pdf new file mode 100644 index 0000000000000..263f4f262530f Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-square-circle-without-appearance.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-square-circle.pdf b/test/fuzz/corpus/pdf_parser/annotation-square-circle.pdf new file mode 100755 index 0000000000000..4aff07fe0c50e Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-square-circle.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-squiggly-without-appearance.pdf b/test/fuzz/corpus/pdf_parser/annotation-squiggly-without-appearance.pdf new file mode 100644 index 0000000000000..203efebb17d97 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-squiggly-without-appearance.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-squiggly.pdf b/test/fuzz/corpus/pdf_parser/annotation-squiggly.pdf new file mode 100644 index 0000000000000..32655700d91b5 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-squiggly.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-stamp.pdf b/test/fuzz/corpus/pdf_parser/annotation-stamp.pdf new file mode 100644 index 0000000000000..625ae3ac69950 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-stamp.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-strikeout-without-appearance.pdf b/test/fuzz/corpus/pdf_parser/annotation-strikeout-without-appearance.pdf new file mode 100644 index 0000000000000..b8c8cab3cba97 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-strikeout-without-appearance.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-strikeout.pdf b/test/fuzz/corpus/pdf_parser/annotation-strikeout.pdf new file mode 100644 index 0000000000000..ede841870fc81 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-strikeout.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-text-widget.pdf b/test/fuzz/corpus/pdf_parser/annotation-text-widget.pdf new file mode 100644 index 0000000000000..6cf0b77ccc64b Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-text-widget.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-text-without-popup.pdf b/test/fuzz/corpus/pdf_parser/annotation-text-without-popup.pdf new file mode 100644 index 0000000000000..5c02df1df924c Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-text-without-popup.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-tx.pdf b/test/fuzz/corpus/pdf_parser/annotation-tx.pdf new file mode 100644 index 0000000000000..d62db2e55be9f Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-tx.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-tx2.pdf b/test/fuzz/corpus/pdf_parser/annotation-tx2.pdf new file mode 100644 index 0000000000000..383dd4ec8592a Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-tx2.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-tx3.pdf b/test/fuzz/corpus/pdf_parser/annotation-tx3.pdf new file mode 100644 index 0000000000000..4df7bd1833487 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-tx3.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-underline-without-appearance.pdf b/test/fuzz/corpus/pdf_parser/annotation-underline-without-appearance.pdf new file mode 100644 index 0000000000000..bb7526dc549dd Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-underline-without-appearance.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation-underline.pdf b/test/fuzz/corpus/pdf_parser/annotation-underline.pdf new file mode 100644 index 0000000000000..8bc4c95207dac Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation-underline.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation_hidden_noview.pdf b/test/fuzz/corpus/pdf_parser/annotation_hidden_noview.pdf new file mode 100644 index 0000000000000..9475158b6c391 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation_hidden_noview.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/annotation_hidden_print.pdf b/test/fuzz/corpus/pdf_parser/annotation_hidden_print.pdf new file mode 100644 index 0000000000000..827a9320b1596 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/annotation_hidden_print.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/arial_unicode_ab_cidfont.pdf b/test/fuzz/corpus/pdf_parser/arial_unicode_ab_cidfont.pdf new file mode 100644 index 0000000000000..e5c97b882ac15 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/arial_unicode_ab_cidfont.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/arial_unicode_en_cidfont.pdf b/test/fuzz/corpus/pdf_parser/arial_unicode_en_cidfont.pdf new file mode 100644 index 0000000000000..6c90e41e3355a Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/arial_unicode_en_cidfont.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/bug1019475_2.pdf b/test/fuzz/corpus/pdf_parser/bug1019475_2.pdf new file mode 100644 index 0000000000000..569b5f6ce212b Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/bug1019475_2.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/bug1072164.pdf b/test/fuzz/corpus/pdf_parser/bug1072164.pdf new file mode 100644 index 0000000000000..c3df5c13c27a8 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/bug1072164.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/bug1538111.pdf b/test/fuzz/corpus/pdf_parser/bug1538111.pdf new file mode 100644 index 0000000000000..deac036e184c4 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/bug1538111.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/bug1723568.pdf b/test/fuzz/corpus/pdf_parser/bug1723568.pdf new file mode 100644 index 0000000000000..ff58ff6f1b230 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/bug1723568.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/bug1901253.pdf b/test/fuzz/corpus/pdf_parser/bug1901253.pdf new file mode 100644 index 0000000000000..740768518d8b0 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/bug1901253.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/cid_cff.pdf b/test/fuzz/corpus/pdf_parser/cid_cff.pdf new file mode 100644 index 0000000000000..264410b61e6bc Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/cid_cff.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/complex_ttf_font.pdf b/test/fuzz/corpus/pdf_parser/complex_ttf_font.pdf new file mode 100644 index 0000000000000..284caabe4c4dc Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/complex_ttf_font.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/decodeACSuccessive.pdf b/test/fuzz/corpus/pdf_parser/decodeACSuccessive.pdf new file mode 100644 index 0000000000000..ed05a3cf5d464 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/decodeACSuccessive.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/font_ascent_descent.pdf b/test/fuzz/corpus/pdf_parser/font_ascent_descent.pdf new file mode 100755 index 0000000000000..85872bcbbdc6c Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/font_ascent_descent.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue11740_reduced.pdf b/test/fuzz/corpus/pdf_parser/issue11740_reduced.pdf new file mode 100644 index 0000000000000..069bf0514548f Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue11740_reduced.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue13107_reduced.pdf b/test/fuzz/corpus/pdf_parser/issue13107_reduced.pdf new file mode 100644 index 0000000000000..60e59492ff43a Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue13107_reduced.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue13433.pdf b/test/fuzz/corpus/pdf_parser/issue13433.pdf new file mode 100644 index 0000000000000..a89454239fdca Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue13433.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue14256.pdf b/test/fuzz/corpus/pdf_parser/issue14256.pdf new file mode 100644 index 0000000000000..2f20d465c3a90 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue14256.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue17069.pdf b/test/fuzz/corpus/pdf_parser/issue17069.pdf new file mode 100755 index 0000000000000..041823a94c807 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue17069.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue17332.pdf b/test/fuzz/corpus/pdf_parser/issue17332.pdf new file mode 100644 index 0000000000000..b278a477f4c53 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue17332.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue17679.pdf b/test/fuzz/corpus/pdf_parser/issue17679.pdf new file mode 100644 index 0000000000000..664dac7aa26ff Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue17679.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue19695.pdf b/test/fuzz/corpus/pdf_parser/issue19695.pdf new file mode 100644 index 0000000000000..a3be8e9f15006 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue19695.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue19835.pdf b/test/fuzz/corpus/pdf_parser/issue19835.pdf new file mode 100644 index 0000000000000..7fe0cce66f0ab Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue19835.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue1985.pdf b/test/fuzz/corpus/pdf_parser/issue1985.pdf new file mode 100644 index 0000000000000..eca11e4a25490 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue1985.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue19971.pdf b/test/fuzz/corpus/pdf_parser/issue19971.pdf new file mode 100644 index 0000000000000..9d1ecd988d1ca Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue19971.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue2856.pdf b/test/fuzz/corpus/pdf_parser/issue2856.pdf new file mode 100644 index 0000000000000..0f94b0c0ab01d Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue2856.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue3351.3.pdf b/test/fuzz/corpus/pdf_parser/issue3351.3.pdf new file mode 100644 index 0000000000000..7cb50d425d584 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue3351.3.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue3584.pdf b/test/fuzz/corpus/pdf_parser/issue3584.pdf new file mode 100644 index 0000000000000..144f1a5548ab4 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue3584.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue4061.pdf b/test/fuzz/corpus/pdf_parser/issue4061.pdf new file mode 100644 index 0000000000000..ace045d5cb09c Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue4061.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue5470.pdf b/test/fuzz/corpus/pdf_parser/issue5470.pdf new file mode 100644 index 0000000000000..6962d1f1a8440 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue5470.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue5564_reduced.pdf b/test/fuzz/corpus/pdf_parser/issue5564_reduced.pdf new file mode 100644 index 0000000000000..0eddb63e51dd2 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue5564_reduced.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue5686.pdf b/test/fuzz/corpus/pdf_parser/issue5686.pdf new file mode 100644 index 0000000000000..6525d1107bee4 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue5686.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue6286.pdf b/test/fuzz/corpus/pdf_parser/issue6286.pdf new file mode 100644 index 0000000000000..d5e9b47f92f34 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue6286.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue6737.pdf b/test/fuzz/corpus/pdf_parser/issue6737.pdf new file mode 100644 index 0000000000000..f4f261d55dda1 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue6737.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue6894.pdf b/test/fuzz/corpus/pdf_parser/issue6894.pdf new file mode 100644 index 0000000000000..7220f7c0e3820 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue6894.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue7014.pdf b/test/fuzz/corpus/pdf_parser/issue7014.pdf new file mode 100644 index 0000000000000..988356f7e431c Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue7014.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue8697.pdf b/test/fuzz/corpus/pdf_parser/issue8697.pdf new file mode 100644 index 0000000000000..c36e8e89deca8 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue8697.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue8707.pdf b/test/fuzz/corpus/pdf_parser/issue8707.pdf new file mode 100644 index 0000000000000..ffc5a3d6ad2fc Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue8707.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue9458.pdf b/test/fuzz/corpus/pdf_parser/issue9458.pdf new file mode 100644 index 0000000000000..8efffd47e9f17 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue9458.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/issue9915_reduced.pdf b/test/fuzz/corpus/pdf_parser/issue9915_reduced.pdf new file mode 100644 index 0000000000000..f515595a90a23 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/issue9915_reduced.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/link-annotation-border.pdf b/test/fuzz/corpus/pdf_parser/link-annotation-border.pdf new file mode 100644 index 0000000000000..56a7e373f0551 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/link-annotation-border.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/minimal.pdf b/test/fuzz/corpus/pdf_parser/minimal.pdf new file mode 100644 index 0000000000000..12930a04acca4 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/minimal.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/mixedfonts.pdf b/test/fuzz/corpus/pdf_parser/mixedfonts.pdf new file mode 100644 index 0000000000000..82bdbec34a2d2 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/mixedfonts.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/mmtype1.pdf b/test/fuzz/corpus/pdf_parser/mmtype1.pdf new file mode 100644 index 0000000000000..84786069e816b Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/mmtype1.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/pattern_text_embedded_font.pdf b/test/fuzz/corpus/pdf_parser/pattern_text_embedded_font.pdf new file mode 100644 index 0000000000000..96d895022739b Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/pattern_text_embedded_font.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/rc_annotation.pdf b/test/fuzz/corpus/pdf_parser/rc_annotation.pdf new file mode 100644 index 0000000000000..08fffb4139615 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/rc_annotation.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/simpletype3font.pdf b/test/fuzz/corpus/pdf_parser/simpletype3font.pdf new file mode 100644 index 0000000000000..f6fc5714cff1b Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/simpletype3font.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/standard_fonts.pdf b/test/fuzz/corpus/pdf_parser/standard_fonts.pdf new file mode 100644 index 0000000000000..348b551a1c5c5 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/standard_fonts.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/text_clip_cff_cid.pdf b/test/fuzz/corpus/pdf_parser/text_clip_cff_cid.pdf new file mode 100644 index 0000000000000..241588f534927 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/text_clip_cff_cid.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/tracemonkey_annotation_on_page_8.pdf b/test/fuzz/corpus/pdf_parser/tracemonkey_annotation_on_page_8.pdf new file mode 100755 index 0000000000000..3684386a52770 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/tracemonkey_annotation_on_page_8.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/tracemonkey_with_annotations.pdf b/test/fuzz/corpus/pdf_parser/tracemonkey_with_annotations.pdf new file mode 100755 index 0000000000000..0cd83427067d7 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/tracemonkey_with_annotations.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/tracemonkey_with_editable_annotations.pdf b/test/fuzz/corpus/pdf_parser/tracemonkey_with_editable_annotations.pdf new file mode 100755 index 0000000000000..037d9482cd190 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/tracemonkey_with_editable_annotations.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1716047.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1716047.pdf new file mode 100644 index 0000000000000..a0f5622ec2bbc Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1716047.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1716380.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1716380.pdf new file mode 100644 index 0000000000000..c4b16678cf0f3 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1716380.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1716809.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1716809.pdf new file mode 100644 index 0000000000000..77c487f7d8565 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1716809.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1716816.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1716816.pdf new file mode 100644 index 0000000000000..eb048bb1d52c9 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1716816.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1716980.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1716980.pdf new file mode 100644 index 0000000000000..3dbc3e5ed4cfe Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1716980.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1717668_1.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1717668_1.pdf new file mode 100644 index 0000000000000..1992fad38d936 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1717668_1.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1717668_2.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1717668_2.pdf new file mode 100644 index 0000000000000..d8f066a602d0e Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1717668_2.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1717668_3.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1717668_3.pdf new file mode 100644 index 0000000000000..d4476b500a441 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1717668_3.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1717668_4.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1717668_4.pdf new file mode 100644 index 0000000000000..177b823baf557 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1717668_4.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1717681.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1717681.pdf new file mode 100644 index 0000000000000..8df2738bcc86e Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1717681.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1717805.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1717805.pdf new file mode 100644 index 0000000000000..3f639934da91d Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1717805.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1718037.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1718037.pdf new file mode 100644 index 0000000000000..6e286b47a5a0d Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1718037.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1718053.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1718053.pdf new file mode 100644 index 0000000000000..f4d5d54a210f3 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1718053.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1718521_1.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1718521_1.pdf new file mode 100644 index 0000000000000..e255c5d64cc48 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1718521_1.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1718521_2.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1718521_2.pdf new file mode 100644 index 0000000000000..d19f992acdc18 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1718521_2.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1718521_3.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1718521_3.pdf new file mode 100644 index 0000000000000..c26bf8997faa0 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1718521_3.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1718670_1.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1718670_1.pdf new file mode 100644 index 0000000000000..130300a052d7e Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1718670_1.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1718725.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1718725.pdf new file mode 100644 index 0000000000000..cc19a9b4ebd6e Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1718725.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1718735.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1718735.pdf new file mode 100644 index 0000000000000..a5a58048d5548 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1718735.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1718740.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1718740.pdf new file mode 100644 index 0000000000000..895d1d8f41508 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1718740.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1718741.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1718741.pdf new file mode 100644 index 0000000000000..5d06020a7484d Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1718741.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1720888.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1720888.pdf new file mode 100644 index 0000000000000..9c7dd23fa9399 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1720888.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1721600.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1721600.pdf new file mode 100644 index 0000000000000..ad29e306d5b0b Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1721600.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1722029.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1722029.pdf new file mode 100644 index 0000000000000..028f572500e35 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1722029.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1722030_1.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1722030_1.pdf new file mode 100644 index 0000000000000..dc6e0da9c1b51 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1722030_1.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1722038.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1722038.pdf new file mode 100644 index 0000000000000..e909574ba42bb Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1722038.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1729877.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1729877.pdf new file mode 100644 index 0000000000000..10187e5b61bb6 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1729877.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1735738.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1735738.pdf new file mode 100644 index 0000000000000..c98a9b7a21870 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1735738.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1739502.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1739502.pdf new file mode 100644 index 0000000000000..c83239e737d3f Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1739502.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_bug1998843.pdf b/test/fuzz/corpus/pdf_parser/xfa_bug1998843.pdf new file mode 100644 index 0000000000000..4c9c40591f8c1 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_bug1998843.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_filled_imm1344e.pdf b/test/fuzz/corpus/pdf_parser/xfa_filled_imm1344e.pdf new file mode 100644 index 0000000000000..606a4d926db77 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_filled_imm1344e.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_issue13213.pdf b/test/fuzz/corpus/pdf_parser/xfa_issue13213.pdf new file mode 100644 index 0000000000000..0f2733eb86a61 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_issue13213.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_issue13500.pdf b/test/fuzz/corpus/pdf_parser/xfa_issue13500.pdf new file mode 100644 index 0000000000000..79f84809ca841 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_issue13500.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_issue13611.pdf b/test/fuzz/corpus/pdf_parser/xfa_issue13611.pdf new file mode 100644 index 0000000000000..ca049b732c816 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_issue13611.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_issue13679.pdf b/test/fuzz/corpus/pdf_parser/xfa_issue13679.pdf new file mode 100644 index 0000000000000..fca01b1c6a1b3 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_issue13679.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_issue13855.pdf b/test/fuzz/corpus/pdf_parser/xfa_issue13855.pdf new file mode 100644 index 0000000000000..6284c591ff7fa Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_issue13855.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_issue13994.pdf b/test/fuzz/corpus/pdf_parser/xfa_issue13994.pdf new file mode 100644 index 0000000000000..7712a216c3296 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_issue13994.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_issue14071.pdf b/test/fuzz/corpus/pdf_parser/xfa_issue14071.pdf new file mode 100644 index 0000000000000..f241c37235070 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_issue14071.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_issue14144.pdf b/test/fuzz/corpus/pdf_parser/xfa_issue14144.pdf new file mode 100644 index 0000000000000..692e3ae730b7f Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_issue14144.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_issue14150.pdf b/test/fuzz/corpus/pdf_parser/xfa_issue14150.pdf new file mode 100644 index 0000000000000..d45983ec0f591 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_issue14150.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xfa_issue14315.pdf b/test/fuzz/corpus/pdf_parser/xfa_issue14315.pdf new file mode 100644 index 0000000000000..3dde6e3d27096 Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xfa_issue14315.pdf differ diff --git a/test/fuzz/corpus/pdf_parser/xobject-image.pdf b/test/fuzz/corpus/pdf_parser/xobject-image.pdf new file mode 100644 index 0000000000000..2d4468c4dc4af Binary files /dev/null and b/test/fuzz/corpus/pdf_parser/xobject-image.pdf differ diff --git a/test/fuzz/corpus/ps_parser/complex.ps b/test/fuzz/corpus/ps_parser/complex.ps new file mode 100644 index 0000000000000..0e60291be9cc4 Binary files /dev/null and b/test/fuzz/corpus/ps_parser/complex.ps differ diff --git a/test/fuzz/corpus/ps_parser/conditional.ps b/test/fuzz/corpus/ps_parser/conditional.ps new file mode 100644 index 0000000000000..6b0e247be447b Binary files /dev/null and b/test/fuzz/corpus/ps_parser/conditional.ps differ diff --git a/test/fuzz/corpus/ps_parser/conditionals.ps b/test/fuzz/corpus/ps_parser/conditionals.ps new file mode 100644 index 0000000000000..d0d4d13ec8c9b Binary files /dev/null and b/test/fuzz/corpus/ps_parser/conditionals.ps differ diff --git a/test/fuzz/corpus/ps_parser/math_ops.ps b/test/fuzz/corpus/ps_parser/math_ops.ps new file mode 100644 index 0000000000000..e6ddf43bb13b8 Binary files /dev/null and b/test/fuzz/corpus/ps_parser/math_ops.ps differ diff --git a/test/fuzz/corpus/ps_parser/simple.ps b/test/fuzz/corpus/ps_parser/simple.ps new file mode 100644 index 0000000000000..da9eefd0ca7dc Binary files /dev/null and b/test/fuzz/corpus/ps_parser/simple.ps differ diff --git a/test/fuzz/corpus/ps_parser/stack_ops.ps b/test/fuzz/corpus/ps_parser/stack_ops.ps new file mode 100644 index 0000000000000..f25b0bec4e494 Binary files /dev/null and b/test/fuzz/corpus/ps_parser/stack_ops.ps differ diff --git a/test/fuzz/corpus/ps_parser/trig.ps b/test/fuzz/corpus/ps_parser/trig.ps new file mode 100644 index 0000000000000..0641ba432917a Binary files /dev/null and b/test/fuzz/corpus/ps_parser/trig.ps differ diff --git a/test/fuzz/corpus/type1_parser/minimal.pfa b/test/fuzz/corpus/type1_parser/minimal.pfa new file mode 100644 index 0000000000000..3406e10b14db2 --- /dev/null +++ b/test/fuzz/corpus/type1_parser/minimal.pfa @@ -0,0 +1,11 @@ +%!PS-AdobeFont-1.0: TestFont 001.000 +%%CreationDate: 1/1/2024 +11 dict begin +/FontType 1 def +/FontName /TestFont def +/FontMatrix [0.001 0 0 0.001 0 0] def +/FontBBox {0 0 1000 1000} def +/Encoding StandardEncoding def +/UniqueID 1000000 def +/PaintType 0 def +currentdict end diff --git a/test/fuzz/corpus/type1_parser/with_charstrings.pfa b/test/fuzz/corpus/type1_parser/with_charstrings.pfa new file mode 100644 index 0000000000000..24eee4714b68c --- /dev/null +++ b/test/fuzz/corpus/type1_parser/with_charstrings.pfa @@ -0,0 +1,19 @@ +%!PS-AdobeFont-1.0: TestFont 001.000 +12 dict begin +/FontType 1 def +/FontName /TestFont def +/FontMatrix [0.001 0 0 0.001 0 0] def +/FontBBox {0 -200 1000 800} def +/Encoding StandardEncoding def +/PaintType 0 def +/Private 8 dict dup begin +/BlueValues [-10 0 700 710] def +/StdHW [80] def +/StdVW [100] def +end def +/CharStrings 2 dict dup begin +/.notdef {} def +/A {} def +end def +currentdict end +/TestFont exch definefont pop diff --git a/test/fuzz/corpus/xfa_parser/complex_form.xfa b/test/fuzz/corpus/xfa_parser/complex_form.xfa new file mode 100644 index 0000000000000..5bdc48a367c7b --- /dev/null +++ b/test/fuzz/corpus/xfa_parser/complex_form.xfa @@ -0,0 +1,36 @@ + + + + diff --git a/test/fuzz/corpus/xfa_parser/minimal.xfa b/test/fuzz/corpus/xfa_parser/minimal.xfa new file mode 100644 index 0000000000000..8c529a3772d44 --- /dev/null +++ b/test/fuzz/corpus/xfa_parser/minimal.xfa @@ -0,0 +1,10 @@ + + + + diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1716047.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1716047.pdf new file mode 100644 index 0000000000000..a0f5622ec2bbc Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1716047.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1716380.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1716380.pdf new file mode 100644 index 0000000000000..c4b16678cf0f3 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1716380.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1716809.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1716809.pdf new file mode 100644 index 0000000000000..77c487f7d8565 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1716809.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1716816.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1716816.pdf new file mode 100644 index 0000000000000..eb048bb1d52c9 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1716816.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1716980.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1716980.pdf new file mode 100644 index 0000000000000..3dbc3e5ed4cfe Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1716980.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1717668_1.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1717668_1.pdf new file mode 100644 index 0000000000000..1992fad38d936 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1717668_1.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1717668_2.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1717668_2.pdf new file mode 100644 index 0000000000000..d8f066a602d0e Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1717668_2.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1717668_3.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1717668_3.pdf new file mode 100644 index 0000000000000..d4476b500a441 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1717668_3.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1717668_4.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1717668_4.pdf new file mode 100644 index 0000000000000..177b823baf557 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1717668_4.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1717681.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1717681.pdf new file mode 100644 index 0000000000000..8df2738bcc86e Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1717681.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1717805.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1717805.pdf new file mode 100644 index 0000000000000..3f639934da91d Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1717805.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1718037.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1718037.pdf new file mode 100644 index 0000000000000..6e286b47a5a0d Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1718037.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1718053.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1718053.pdf new file mode 100644 index 0000000000000..f4d5d54a210f3 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1718053.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1718521_1.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1718521_1.pdf new file mode 100644 index 0000000000000..e255c5d64cc48 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1718521_1.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1718521_2.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1718521_2.pdf new file mode 100644 index 0000000000000..d19f992acdc18 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1718521_2.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1718521_3.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1718521_3.pdf new file mode 100644 index 0000000000000..c26bf8997faa0 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1718521_3.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1718670_1.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1718670_1.pdf new file mode 100644 index 0000000000000..130300a052d7e Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1718670_1.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1718725.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1718725.pdf new file mode 100644 index 0000000000000..cc19a9b4ebd6e Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1718725.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1718735.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1718735.pdf new file mode 100644 index 0000000000000..a5a58048d5548 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1718735.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1718740.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1718740.pdf new file mode 100644 index 0000000000000..895d1d8f41508 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1718740.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1718741.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1718741.pdf new file mode 100644 index 0000000000000..5d06020a7484d Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1718741.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1720888.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1720888.pdf new file mode 100644 index 0000000000000..9c7dd23fa9399 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1720888.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1721600.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1721600.pdf new file mode 100644 index 0000000000000..ad29e306d5b0b Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1721600.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1722029.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1722029.pdf new file mode 100644 index 0000000000000..028f572500e35 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1722029.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1722030_1.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1722030_1.pdf new file mode 100644 index 0000000000000..dc6e0da9c1b51 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1722030_1.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1722038.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1722038.pdf new file mode 100644 index 0000000000000..e909574ba42bb Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1722038.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1729877.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1729877.pdf new file mode 100644 index 0000000000000..10187e5b61bb6 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1729877.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1735738.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1735738.pdf new file mode 100644 index 0000000000000..c98a9b7a21870 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1735738.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1739502.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1739502.pdf new file mode 100644 index 0000000000000..c83239e737d3f Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1739502.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_bug1998843.pdf b/test/fuzz/corpus/xfa_parser/xfa_bug1998843.pdf new file mode 100644 index 0000000000000..4c9c40591f8c1 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_bug1998843.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_filled_imm1344e.pdf b/test/fuzz/corpus/xfa_parser/xfa_filled_imm1344e.pdf new file mode 100644 index 0000000000000..606a4d926db77 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_filled_imm1344e.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_issue13213.pdf b/test/fuzz/corpus/xfa_parser/xfa_issue13213.pdf new file mode 100644 index 0000000000000..0f2733eb86a61 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_issue13213.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_issue13500.pdf b/test/fuzz/corpus/xfa_parser/xfa_issue13500.pdf new file mode 100644 index 0000000000000..79f84809ca841 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_issue13500.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_issue13611.pdf b/test/fuzz/corpus/xfa_parser/xfa_issue13611.pdf new file mode 100644 index 0000000000000..ca049b732c816 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_issue13611.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_issue13679.pdf b/test/fuzz/corpus/xfa_parser/xfa_issue13679.pdf new file mode 100644 index 0000000000000..fca01b1c6a1b3 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_issue13679.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_issue13855.pdf b/test/fuzz/corpus/xfa_parser/xfa_issue13855.pdf new file mode 100644 index 0000000000000..6284c591ff7fa Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_issue13855.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_issue13994.pdf b/test/fuzz/corpus/xfa_parser/xfa_issue13994.pdf new file mode 100644 index 0000000000000..7712a216c3296 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_issue13994.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_issue14071.pdf b/test/fuzz/corpus/xfa_parser/xfa_issue14071.pdf new file mode 100644 index 0000000000000..f241c37235070 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_issue14071.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_issue14144.pdf b/test/fuzz/corpus/xfa_parser/xfa_issue14144.pdf new file mode 100644 index 0000000000000..692e3ae730b7f Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_issue14144.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_issue14150.pdf b/test/fuzz/corpus/xfa_parser/xfa_issue14150.pdf new file mode 100644 index 0000000000000..d45983ec0f591 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_issue14150.pdf differ diff --git a/test/fuzz/corpus/xfa_parser/xfa_issue14315.pdf b/test/fuzz/corpus/xfa_parser/xfa_issue14315.pdf new file mode 100644 index 0000000000000..3dde6e3d27096 Binary files /dev/null and b/test/fuzz/corpus/xfa_parser/xfa_issue14315.pdf differ diff --git a/test/fuzz/corpus/xml_parser/minimal.xml b/test/fuzz/corpus/xml_parser/minimal.xml new file mode 100644 index 0000000000000..2cfa52b214ce6 --- /dev/null +++ b/test/fuzz/corpus/xml_parser/minimal.xml @@ -0,0 +1,4 @@ + + + Hello + diff --git a/test/fuzz/corpus/xml_parser/with_attrs.xml b/test/fuzz/corpus/xml_parser/with_attrs.xml new file mode 100644 index 0000000000000..0666fab089bb4 --- /dev/null +++ b/test/fuzz/corpus/xml_parser/with_attrs.xml @@ -0,0 +1,6 @@ + + +
+ Sample text +
+
diff --git a/test/fuzz/corpus/xml_parser/xmp_metadata.xml b/test/fuzz/corpus/xml_parser/xmp_metadata.xml new file mode 100644 index 0000000000000..1f02be4e466fe --- /dev/null +++ b/test/fuzz/corpus/xml_parser/xmp_metadata.xml @@ -0,0 +1,14 @@ + + + + + Test Document + Author Name + 2024-01-01T00:00:00Z + Test Producer + + + diff --git a/test/fuzz/crypto.fuzz.js b/test/fuzz/crypto.fuzz.js new file mode 100644 index 0000000000000..d9016617c1449 --- /dev/null +++ b/test/fuzz/crypto.fuzz.js @@ -0,0 +1,108 @@ +// 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 crypto operations (encryption/decryption). + * Tests RC4, AES-128, AES-256 ciphers and password handling. + */ + +const MAX_INPUT_SIZE = 64 * 1024; // 64KB limit + +let ARCFourCipher = null; +let AES128Cipher = null; +let AES256Cipher = null; +let calculateMD5 = null; +let calculateSHA256 = null; + +async function init() { + if (ARCFourCipher) return; + const cryptoModule = await import("../../build/lib-legacy/core/crypto.js"); + ARCFourCipher = cryptoModule.ARCFourCipher; + AES128Cipher = cryptoModule.AES128Cipher; + AES256Cipher = cryptoModule.AES256Cipher; + + const md5Module = await import("../../build/lib-legacy/core/calculate_md5.js"); + calculateMD5 = md5Module.calculateMD5; + + const sha256Module = await import("../../build/lib-legacy/core/calculate_sha256.js"); + calculateSHA256 = sha256Module.calculateSHA256; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + + if (data.length < 32 || data.length > MAX_INPUT_SIZE) { + return; + } + + try { + // Extract key and data from input + const keyLen = Math.min(data[0] % 32 + 1, 32); + const key = new Uint8Array(data.slice(1, 1 + keyLen)); + const payload = new Uint8Array(data.slice(1 + keyLen)); + + if (payload.length === 0) { + return; + } + + // Test RC4 cipher + try { + const rc4 = new ARCFourCipher(key); + rc4.encryptBlock(payload.slice()); + } catch (e) { + // Expected for malformed input + } + + // Test AES-128 if key is right size + if (key.length >= 16) { + try { + const aes128 = new AES128Cipher(key.slice(0, 16)); + aes128.decryptBlock(payload.slice()); + } catch (e) { + // Expected for malformed input + } + } + + // Test AES-256 if key is right size + if (key.length >= 32) { + try { + const aes256 = new AES256Cipher(key.slice(0, 32)); + aes256.decryptBlock(payload.slice()); + } catch (e) { + // Expected for malformed input + } + } + + // Test hash functions + try { + calculateMD5(payload, 0, payload.length); + calculateSHA256(payload, 0, payload.length); + } catch (e) { + // Expected for malformed input + } + + } catch (e) { + // Expected exceptions for malformed crypto input + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; + } + } +}; diff --git a/test/fuzz/dictionaries/ccitt_stream.dict b/test/fuzz/dictionaries/ccitt_stream.dict new file mode 100644 index 0000000000000..b60dd5eb4536f --- /dev/null +++ b/test/fuzz/dictionaries/ccitt_stream.dict @@ -0,0 +1,51 @@ +# CCITT Fax format dictionary +# EOL marker (End of Line) +"\x00\x01" +"\x80\x00" + +# White run codes +"\x35" +"\x07" +"\x07\x08" +"\x08" + +# Black run codes +"\x02" +"\x03" +"\x02\x03" + +# 2D mode codes +"\x01" +"\x02" +"\x03" +"\x04" +"\x05" +"\x06" +"\x07" + +# Fill bits +"\x00" +"\xff" + +# RTC (Return To Control) +"\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" + +# Common pattern bytes +"\x80" +"\x40" +"\x20" +"\x10" +"\x08" +"\x04" +"\x02" +"\x01" + +# Length markers +"\x00\x00" +"\x00\x01" +"\x00\x10" +"\x00\x80" +"\x01\x00" +"\x04\x00" +"\x08\x00" +"\x10\x00" diff --git a/test/fuzz/dictionaries/cff_parser.dict b/test/fuzz/dictionaries/cff_parser.dict new file mode 100644 index 0000000000000..55498634944be --- /dev/null +++ b/test/fuzz/dictionaries/cff_parser.dict @@ -0,0 +1,94 @@ +# CFF (Compact Font Format) dictionary +# CFF header +"\x01\x00" +"\x01\x00\x04\x01" + +# Top DICT operators +"\x00" +"\x01" +"\x02" +"\x03" +"\x04" +"\x05" +"\x06" +"\x07" +"\x08" +"\x0c\x00" +"\x0c\x01" +"\x0c\x02" +"\x0c\x03" +"\x0c\x04" +"\x0c\x05" +"\x0c\x06" +"\x0c\x07" +"\x0c\x08" +"\x0c\x09" +"\x0c\x0a" +"\x0c\x0b" +"\x0c\x0c" +"\x0c\x14" +"\x0c\x15" +"\x0c\x16" +"\x0c\x17" +"\x0c\x18" +"\x0c\x1e" +"\x0c\x1f" +"\x0c\x20" +"\x0c\x21" +"\x0c\x22" +"\x0c\x23" +"\x0c\x24" + +# CharString operators +"\x01" +"\x03" +"\x04" +"\x05" +"\x06" +"\x07" +"\x08" +"\x0a" +"\x0b" +"\x0c" +"\x0e" +"\x12" +"\x13" +"\x14" +"\x15" +"\x16" +"\x17" +"\x18" +"\x19" +"\x1a" +"\x1b" +"\x1c" +"\x1d" +"\x1e" +"\x1f" + +# Integer encodings +"\x1c\x00\x00" +"\x1d\x00\x00\x00\x00" +"\x20" +"\xf6" +"\xf7\x00" +"\xfb\x00" + +# Common SID values +".notdef" +"space" +"zero" +"one" +"A" + +# Index counts +"\x00\x01" +"\x00\x02" +"\x00\x03" +"\x00\x04" + +# Offset sizes +"\x01" +"\x02" +"\x03" +"\x04" diff --git a/test/fuzz/dictionaries/cmap_parser.dict b/test/fuzz/dictionaries/cmap_parser.dict new file mode 100644 index 0000000000000..ba12286a67852 --- /dev/null +++ b/test/fuzz/dictionaries/cmap_parser.dict @@ -0,0 +1,67 @@ +# CMap format dictionary +# Header +"/CIDInit" +"/ProcSet" +"findresource" +"begin" +"12 dict" +"begincmap" +"endcmap" +"CMapName" +"currentdict" +"CMapType" +"end" + +# CMap operators +"begincodespacerange" +"endcodespacerange" +"beginbfchar" +"endbfchar" +"beginbfrange" +"endbfrange" +"begincidchar" +"endcidchar" +"begincidrange" +"endcidrange" +"beginnotdefchar" +"endnotdefchar" +"beginnotdefrange" +"endnotdefrange" + +# Code values +"<00>" +"<0000>" +"<00000000>" +"" +"" +"" +"<0020>" +"<0041>" +"<005a>" +"<0061>" +"<007a>" + +# Registry/Ordering +"/CIDSystemInfo" +"/Registry" +"/Ordering" +"/Supplement" +"(Adobe)" +"(Identity)" +"(Japan1)" +"(Korea1)" +"(CNS1)" +"(GB1)" + +# Common CMap names +"/Identity-H" +"/Identity-V" +"/UniJIS-UTF16-H" +"/UniGB-UTF16-H" +"/UniCNS-UTF16-H" +"/UniKS-UTF16-H" + +# Define operator +"def" +"readonly" +"pop" diff --git a/test/fuzz/dictionaries/colorspace.dict b/test/fuzz/dictionaries/colorspace.dict new file mode 100644 index 0000000000000..5b702dbbebd5e --- /dev/null +++ b/test/fuzz/dictionaries/colorspace.dict @@ -0,0 +1,68 @@ +# PDF Colorspace dictionary +# Device colorspaces +"/DeviceGray" +"/DeviceRGB" +"/DeviceCMYK" +"/DeviceN" + +# CIE-based colorspaces +"/CalGray" +"/CalRGB" +"/Lab" +"/ICCBased" + +# Special colorspaces +"/Indexed" +"/Separation" +"/Pattern" + +# Colorspace keys +"/WhitePoint" +"/BlackPoint" +"/Gamma" +"/Matrix" +"/Range" +"/N" +"/Alternate" +"/Tint" +"/Base" +"/HiVal" +"/Lookup" + +# ICC Profile header +"acsp" +"ADBE" +"APPL" +"MSFT" +"mntr" +"scnr" +"prtr" +"RGB " +"CMYK" +"GRAY" +"XYZ " +"Lab " + +# Common values +"[0 1]" +"[0 0 0]" +"[1 1 1]" +"[0.9505 1 1.089]" +"[0 0 0 0]" +"[1 1 1 1]" +"[0 100 -128 127 -128 127]" + +# ICC tag signatures +"desc" +"cprt" +"wtpt" +"bkpt" +"rXYZ" +"gXYZ" +"bXYZ" +"rTRC" +"gTRC" +"bTRC" +"A2B0" +"B2A0" +"chad" diff --git a/test/fuzz/dictionaries/crypto.dict b/test/fuzz/dictionaries/crypto.dict new file mode 100644 index 0000000000000..5d42f93519e03 --- /dev/null +++ b/test/fuzz/dictionaries/crypto.dict @@ -0,0 +1,50 @@ +# PDF crypto/encryption dictionary +# Encryption versions +"\x00" +"\x01" +"\x02" +"\x03" +"\x04" +"\x05" + +# Key lengths +"\x28" +"\x40" +"\x80" +"\x100" + +# Common password bytes +"\x28\xbf\x4e\x5e\x4e\x75\x8a\x41\x64\x00\x4e\x56\xff\xfa\x01\x08" +"\x2e\x2e\x00\xb6\xd0\x68\x3e\x80\x2f\x0c\xa9\xfe\x64\x53\x69\x7a" + +# AES padding +"\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10" +"\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f" +"\x01" +"\x02\x02" +"\x03\x03\x03" +"\x04\x04\x04\x04" + +# AES block size data +"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + +# RC4 test patterns +"\x00\x00\x00\x00\x00" +"\xff\xff\xff\xff\xff" + +# SHA-256 padding +"\x80" +"\x00\x00\x00\x00\x00\x00\x00" + +# Common hash lengths +"\x10" +"\x14" +"\x20" +"\x30" +"\x40" + +# Permissions flags +"\xff\xff\xff\xff" +"\x00\x00\x00\x00" +"\xfc\xff\xff\xff" +"\xf8\xff\xff\xff" diff --git a/test/fuzz/dictionaries/flate_stream.dict b/test/fuzz/dictionaries/flate_stream.dict new file mode 100644 index 0000000000000..033d6ddce571e --- /dev/null +++ b/test/fuzz/dictionaries/flate_stream.dict @@ -0,0 +1,61 @@ +# Deflate/Zlib format dictionary +# Zlib headers (CMF, FLG) +"\x78\x01" +"\x78\x5e" +"\x78\x9c" +"\x78\xda" + +# Raw deflate block types +"\x00" +"\x01" +"\x02" +"\x03" + +# Final block flag +"\x01" + +# Non-compressed block +"\x00\x00\xff\xff" +"\x01\x00\xfe\xff" + +# Fixed Huffman block +"\x03" + +# Dynamic Huffman block +"\x04" +"\x05" + +# Common literal/length codes +"\x00" +"\x01" +"\x02" +"\x03" +"\x04" +"\x0a" +"\x0d" +"\x20" +"\xff" + +# Distance codes +"\x00\x00" +"\x00\x01" +"\x00\x02" +"\x01\x00" + +# End of block marker +"\x00" + +# ADLER-32 checksum patterns +"\x00\x00\x00\x01" +"\x00\x01\x00\x01" +"\xff\xff\xff\xff" + +# Repeat codes +"\xed" +"\xee" +"\xef" + +# Back references +"\x01\x01" +"\x02\x02" +"\x03\x03" diff --git a/test/fuzz/dictionaries/formcalc_parser.dict b/test/fuzz/dictionaries/formcalc_parser.dict new file mode 100644 index 0000000000000..0e754f3722f31 --- /dev/null +++ b/test/fuzz/dictionaries/formcalc_parser.dict @@ -0,0 +1,143 @@ +# FormCalc script language dictionary +# Keywords +"if" +"then" +"else" +"elseif" +"endif" +"while" +"endwhile" +"for" +"to" +"step" +"endfor" +"foreach" +"in" +"endforeach" +"do" +"break" +"continue" +"func" +"endfunc" +"return" +"var" +"null" +"end" + +# Operators +"+" +"-" +"*" +"/" +"==" +"!=" +"<>" +"<" +">" +"<=" +">=" +"&" +"|" +"not" +"and" +"or" +"eq" +"ne" +"lt" +"le" +"gt" +"ge" + +# Built-in functions +"Abs(" +"Avg(" +"Ceil(" +"Count(" +"Date(" +"Date2Num(" +"DateFmt(" +"Decode(" +"Encode(" +"Eval(" +"Exists(" +"Floor(" +"Format(" +"Get(" +"HasValue(" +"If(" +"IsoDate2Num(" +"IsoTime2Num(" +"Left(" +"Len(" +"LocalDateFmt(" +"LocalTimeFmt(" +"Lower(" +"Ltrim(" +"Max(" +"Min(" +"Mod(" +"NPV(" +"Num2Date(" +"Num2GMTime(" +"Num2Time(" +"Oneof(" +"Parse(" +"Post(" +"Put(" +"Ref(" +"Replace(" +"Right(" +"Round(" +"Rtrim(" +"Space(" +"Str(" +"Stuff(" +"Substr(" +"Sum(" +"Term(" +"Time(" +"Time2Num(" +"TimeFmt(" +"UnitType(" +"UnitValue(" +"Upper(" +"Uuid(" +"Within(" +"WordNum(" + +# Literals +"0" +"1" +"-1" +"0.0" +"1.0" +"\"\"" +"\"text\"" +"'text'" + +# Assignment +"=" +":=" + +# Punctuation +"(" +")" +"[" +"]" +"," +";" +"." +"$" + +# Field references +"$record" +"$form" +"$data" +"$host" +"$layout" +"$template" +"$event" + +# Comments +"//" +";" diff --git a/test/fuzz/dictionaries/jbig2_image.dict b/test/fuzz/dictionaries/jbig2_image.dict new file mode 100644 index 0000000000000..a82525008f627 --- /dev/null +++ b/test/fuzz/dictionaries/jbig2_image.dict @@ -0,0 +1,79 @@ +# JBIG2 format dictionary +# File header +"\x97\x4a\x42\x32\x0d\x0a\x1a\x0a" + +# Segment header flags +"\x00" +"\x01" +"\x02" +"\x04" +"\x06" +"\x07" +"\x10" +"\x11" +"\x14" +"\x16" +"\x17" +"\x20" +"\x21" +"\x22" +"\x23" +"\x24" +"\x26" +"\x27" +"\x28" +"\x29" +"\x2a" +"\x2b" +"\x30" +"\x31" +"\x32" +"\x33" +"\x38" +"\x39" +"\x3e" + +# Segment types +# Symbol dictionary +"\x00\x00\x00\x00" +# Text region +"\x00\x00\x00\x06" +# Pattern dictionary +"\x00\x00\x00\x10" +# Halftone region +"\x00\x00\x00\x16" +# Generic region +"\x00\x00\x00\x24" +# Refinement region +"\x00\x00\x00\x28" +# Page information +"\x00\x00\x00\x30" +# End of page +"\x00\x00\x00\x31" +# End of file +"\x00\x00\x00\x33" + +# Common lengths +"\x00\x00\x00\x01" +"\x00\x00\x00\x02" +"\x00\x00\x00\x04" +"\x00\x00\x00\x08" +"\x00\x00\x00\x10" +"\x00\x00\x00\x20" +"\x00\x00\x00\x40" +"\x00\x00\x01\x00" +"\x00\x00\x02\x00" +"\xff\xff\xff\xff" + +# Width/Height values +"\x00\x01" +"\x00\x02" +"\x00\x04" +"\x00\x08" +"\x00\x10" +"\x00\x20" +"\x00\x40" +"\x00\x80" +"\x01\x00" +"\x02\x00" +"\x04\x00" diff --git a/test/fuzz/dictionaries/jpeg_image.dict b/test/fuzz/dictionaries/jpeg_image.dict new file mode 100644 index 0000000000000..eb63489c39d26 --- /dev/null +++ b/test/fuzz/dictionaries/jpeg_image.dict @@ -0,0 +1,71 @@ +# JPEG format dictionary +# SOI marker +"\xff\xd8" + +# JFIF/EXIF markers +"\xff\xe0" +"\xff\xe1" + +# APP markers +"\xff\xe0\x00\x10JFIF\x00" +"\xff\xe1\x00\x08Exif\x00\x00" + +# DQT (Define Quantization Table) +"\xff\xdb" + +# DHT (Define Huffman Table) +"\xff\xc4" + +# SOF markers (Start of Frame) +"\xff\xc0" +"\xff\xc1" +"\xff\xc2" +"\xff\xc3" +"\xff\xc5" +"\xff\xc6" +"\xff\xc7" +"\xff\xc9" +"\xff\xca" +"\xff\xcb" +"\xff\xcd" +"\xff\xce" +"\xff\xcf" + +# SOS (Start of Scan) +"\xff\xda" + +# EOI marker +"\xff\xd9" + +# RST markers (Restart) +"\xff\xd0" +"\xff\xd1" +"\xff\xd2" +"\xff\xd3" +"\xff\xd4" +"\xff\xd5" +"\xff\xd6" +"\xff\xd7" + +# DNL (Define Number of Lines) +"\xff\xdc" + +# DRI (Define Restart Interval) +"\xff\xdd" + +# COM (Comment) +"\xff\xfe" + +# Adobe marker +"\xff\xee" +"Adobe" + +# Length bytes +"\x00\x00" +"\x00\x01" +"\x00\x02" +"\x00\x08" +"\x00\x10" +"\x00\x11" +"\x00\x40" +"\xff\xff" diff --git a/test/fuzz/dictionaries/jpx_image.dict b/test/fuzz/dictionaries/jpx_image.dict new file mode 100644 index 0000000000000..80df6f2b0a2c9 --- /dev/null +++ b/test/fuzz/dictionaries/jpx_image.dict @@ -0,0 +1,84 @@ +# JPEG2000 (JP2/JPX) format dictionary +# JP2 signature +"\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a" + +# File type box +"ftyp" +"jp2 " +"jpx " +"jpxb" + +# JP2 header box +"jp2h" + +# Image header box +"ihdr" + +# Color specification box +"colr" + +# Contiguous codestream box +"jp2c" + +# SOC (Start of codestream) +"\xff\x4f" + +# SIZ (Image and tile size) +"\xff\x51" + +# COD (Coding style default) +"\xff\x52" + +# COC (Coding style component) +"\xff\x53" + +# QCD (Quantization default) +"\xff\x5c" + +# QCC (Quantization component) +"\xff\x5d" + +# RGN (Region of interest) +"\xff\x5e" + +# POC (Progression order change) +"\xff\x5f" + +# SOT (Start of tile) +"\xff\x90" + +# SOP (Start of packet) +"\xff\x91" + +# EPH (End of packet header) +"\xff\x92" + +# SOD (Start of data) +"\xff\x93" + +# EOC (End of codestream) +"\xff\xd9" + +# TLM (Tile-part length) +"\xff\x55" + +# PLM/PLT (Packet length) +"\xff\x57" +"\xff\x58" + +# PPM/PPT (Packed packet headers) +"\xff\x60" +"\xff\x61" + +# CRG (Component registration) +"\xff\x63" + +# COM (Comment) +"\xff\x64" + +# Common box sizes +"\x00\x00\x00\x00" +"\x00\x00\x00\x08" +"\x00\x00\x00\x10" +"\x00\x00\x00\x14" +"\x00\x00\x00\x16" diff --git a/test/fuzz/dictionaries/lzw_stream.dict b/test/fuzz/dictionaries/lzw_stream.dict new file mode 100644 index 0000000000000..72f02f29625f3 --- /dev/null +++ b/test/fuzz/dictionaries/lzw_stream.dict @@ -0,0 +1,39 @@ +# LZW compression format dictionary +# Clear code (256) +"\x80\x00" + +# EOD code (257) +"\x80\x40" + +# Initial codes (0-255 literals) +"\x00" +"\x01" +"\x20" +"\x41" +"\x5a" +"\x61" +"\x7a" +"\xff" + +# Common code patterns +"\x80" +"\x81" +"\x82" +"\x83" +"\x84" + +# Extended codes +"\x01\x00" +"\x01\x01" +"\x01\x02" +"\x02\x00" +"\x02\x01" +"\x02\x02" + +# Reset patterns +"\x80\x00\x80\x00" + +# Common byte sequences +"\x00\x00\x00\x00" +"\xff\xff\xff\xff" +"\x01\x02\x03\x04" diff --git a/test/fuzz/dictionaries/pdf_parser.dict b/test/fuzz/dictionaries/pdf_parser.dict new file mode 100644 index 0000000000000..9e4c07482342b --- /dev/null +++ b/test/fuzz/dictionaries/pdf_parser.dict @@ -0,0 +1,150 @@ +# PDF format dictionary +# Magic bytes and version +"%PDF-" +"%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" +"%%EOF" + +# Object markers +"obj" +"endobj" +"stream" +"endstream" +"xref" +"trailer" +"startxref" + +# Common keywords +"/Type" +"/Subtype" +"/Page" +"/Pages" +"/Catalog" +"/Count" +"/Kids" +"/Parent" +"/Resources" +"/Contents" +"/MediaBox" +"/CropBox" +"/BleedBox" +"/TrimBox" +"/ArtBox" +"/Rotate" + +# References +" R" +" 0 R" +" 0 obj" + +# Booleans +"true" +"false" +"null" + +# Delimiters +"<<" +">>" +"[" +"]" +"(" +")" +"<" +">" +"/" + +# Numbers +"0" +"-1" +"65535" +"2147483647" +"-2147483648" +"0.0" +"1.0" +"-0.001" + +# Streams +"/Filter" +"/Length" +"/FlateDecode" +"/LZWDecode" +"/ASCII85Decode" +"/ASCIIHexDecode" +"/RunLengthDecode" +"/CCITTFaxDecode" +"/JBIG2Decode" +"/DCTDecode" +"/JPXDecode" +"/Crypt" + +# Font related +"/Font" +"/BaseFont" +"/FontDescriptor" +"/Encoding" +"/ToUnicode" +"/CIDFont" +"/Type0" +"/Type1" +"/Type3" +"/TrueType" +"/CIDFontType0" +"/CIDFontType2" + +# Image related +"/Image" +"/XObject" +"/Width" +"/Height" +"/BitsPerComponent" +"/ColorSpace" +"/DeviceGray" +"/DeviceRGB" +"/DeviceCMYK" +"/Indexed" +"/ICCBased" + +# Cross-reference streams +"/XRef" +"/Size" +"/Index" +"/W" +"/Prev" +"/Root" +"/Info" +"/ID" + +# Encryption +"/Encrypt" +"/V" +"/R" +"/O" +"/U" +"/P" +"/CF" +"/StdCF" +"/StmF" +"/StrF" +"/AESV2" +"/AESV3" + +# XFA +"/XFA" +"/AcroForm" +"/Fields" +"/NeedAppearances" + +# Special characters +"\x00" +"\x0a" +"\x0d" +"\x09" +"\x0c" +"\x20" diff --git a/test/fuzz/dictionaries/ps_parser.dict b/test/fuzz/dictionaries/ps_parser.dict new file mode 100644 index 0000000000000..9f2fedb718673 --- /dev/null +++ b/test/fuzz/dictionaries/ps_parser.dict @@ -0,0 +1,73 @@ +# PostScript calculator function dictionary +# Stack operations +"dup" +"exch" +"pop" +"copy" +"index" +"roll" + +# Arithmetic +"add" +"sub" +"mul" +"div" +"idiv" +"mod" +"neg" +"abs" +"ceiling" +"floor" +"round" +"truncate" +"sqrt" +"exp" +"ln" +"log" +"sin" +"cos" +"atan" + +# Relational +"eq" +"ne" +"lt" +"le" +"gt" +"ge" + +# Logical +"and" +"or" +"xor" +"not" +"bitshift" + +# Conditionals +"if" +"ifelse" + +# Delimiters +"{" +"}" +"[" +"]" + +# Constants +"true" +"false" + +# Numbers +"0" +"1" +"-1" +"0.0" +"1.0" +"-0.5" +"0.5" +"2" +"10" +"100" +"255" +"360" +"3.14159" diff --git a/test/fuzz/dictionaries/type1_parser.dict b/test/fuzz/dictionaries/type1_parser.dict new file mode 100644 index 0000000000000..87d625b6dec0d --- /dev/null +++ b/test/fuzz/dictionaries/type1_parser.dict @@ -0,0 +1,107 @@ +# Type1 font format dictionary +# Header markers +"%!PS-AdobeFont-1.0" +"%!FontType1" +"%%BeginResource: font" +"%%EndResource" + +# Font dictionary keys +"/FontType" +"/FontMatrix" +"/FontBBox" +"/UniqueID" +"/FontName" +"/FontInfo" +"/Encoding" +"/PaintType" +"/StrokeWidth" + +# FontInfo keys +"/version" +"/Notice" +"/FullName" +"/FamilyName" +"/Weight" +"/ItalicAngle" +"/isFixedPitch" +"/UnderlinePosition" +"/UnderlineThickness" + +# Private dictionary +"/Private" +"/BlueValues" +"/OtherBlues" +"/FamilyBlues" +"/FamilyOtherBlues" +"/BlueScale" +"/BlueShift" +"/BlueFuzz" +"/StdHW" +"/StdVW" +"/StemSnapH" +"/StemSnapV" +"/ForceBold" +"/LanguageGroup" +"/password" +"/lenIV" +"/MinFeature" +"/RndStemUp" +"/Subrs" +"/OtherSubrs" + +# Charstring commands +"callsubr" +"callothersubr" +"pop" +"return" +"seac" +"sbw" +"hsbw" +"endchar" +"rmoveto" +"hmoveto" +"vmoveto" +"rlineto" +"hlineto" +"vlineto" +"rrcurveto" +"hhcurveto" +"hvcurveto" +"rcurveline" +"rlinecurve" +"vhcurveto" +"vvcurveto" +"flex" +"hflex" +"hflex1" +"flex1" +"hstem" +"vstem" +"hstemhm" +"vstemhm" +"hintmask" +"cntrmask" +"div" +"closepath" +"dotsection" + +# Encoding +"/StandardEncoding" +"dup" +"readonly" +"def" +"put" +"for" +"array" +"dict" +"begin" +"end" +"currentdict" +"currentfile" +"eexec" +"mark" +"cleartomark" + +# Boolean +"true" +"false" diff --git a/test/fuzz/dictionaries/xfa_parser.dict b/test/fuzz/dictionaries/xfa_parser.dict new file mode 100644 index 0000000000000..d16b6227931ed --- /dev/null +++ b/test/fuzz/dictionaries/xfa_parser.dict @@ -0,0 +1,120 @@ +# XFA XML format dictionary +# XML declaration +"" +"" + +# XFA namespaces +"xmlns" +"xmlns:xfa" +"xmlns:xdp" +"http://www.xfa.org/schema/xfa-data/1.0/" +"http://ns.adobe.com/xdp/" +"http://www.xfa.org/schema/xfa-template/3.0/" + +# XDP root +"" + +# XFA elements +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" +"" + +# XFA attributes +"name=" +"access=" +"presence=" +"relevant=" +"use=" +"usehref=" +"x=" +"y=" +"w=" +"h=" +"minH=" +"minW=" +"maxH=" +"maxW=" +"layout=" + +# Layout values +"position" +"lr-tb" +"rl-tb" +"tb" +"table" +"row" + +# Access values +"open" +"nonInteractive" +"protected" +"readOnly" + +# Presence values +"visible" +"hidden" +"inactive" +"invisible" + +# Common XML +"<" +">" +"/>" +"" +"" diff --git a/test/fuzz/dictionaries/xml_parser.dict b/test/fuzz/dictionaries/xml_parser.dict new file mode 100644 index 0000000000000..81c60bf0a4cf8 --- /dev/null +++ b/test/fuzz/dictionaries/xml_parser.dict @@ -0,0 +1,85 @@ +# XML format dictionary +# Declarations +"" +"" +"" + +# DOCTYPE +"" + +# Common elements +"" +"" +"" +"" + +# Namespaces +"xmlns" +"xmlns:" +"http://" +"https://" + +# Attributes +"id=" +"name=" +"type=" +"value=" +"href=" +"src=" + +# Text content +"" + +# Comments +"" + +# Processing instructions +"" + +# Entity references +"<" +">" +"&" +"'" +""" +"&#" +"&#x" + +# Delimiters +"<" +">" +"" +"=" +"\"" +"'" +" " + +# Common values +"true" +"false" +"null" +"0" +"1" +"-1" + +# Whitespace +"\x20" +"\x09" +"\x0a" +"\x0d" diff --git a/test/fuzz/flate_stream.fuzz.js b/test/fuzz/flate_stream.fuzz.js new file mode 100644 index 0000000000000..23a547ad87027 --- /dev/null +++ b/test/fuzz/flate_stream.fuzz.js @@ -0,0 +1,66 @@ +// 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 Flate (zlib/deflate) stream decoding. + * This is a critical decompression codec used heavily in PDFs. + */ + +const MAX_INPUT_SIZE = 128 * 1024; // 128KB limit +const MAX_OUTPUT_SIZE = 10 * 1024 * 1024; // 10MB output limit + +let FlateStream = null; +let Stream = null; + +async function init() { + if (FlateStream) return; + const flateModule = await import("../../build/lib-legacy/core/flate_stream.js"); + const streamModule = await import("../../build/lib-legacy/core/stream.js"); + FlateStream = flateModule.FlateStream; + Stream = streamModule.Stream; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + if (data.length === 0 || data.length > MAX_INPUT_SIZE) { + return; + } + + try { + const stream = new Stream(new Uint8Array(data)); + const flateStream = new FlateStream(stream, MAX_OUTPUT_SIZE); + + // Try to read decompressed data + let bytesRead = 0; + let chunk; + while ((chunk = flateStream.getBytes(4096)) && chunk.length > 0) { + bytesRead += chunk.length; + if (bytesRead > MAX_OUTPUT_SIZE) { + break; // Prevent decompression bombs + } + } + } catch (e) { + // Expected exceptions for malformed compressed data + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; + } + } +}; diff --git a/test/fuzz/formcalc_parser.fuzz.js b/test/fuzz/formcalc_parser.fuzz.js new file mode 100644 index 0000000000000..b9da10012d3aa --- /dev/null +++ b/test/fuzz/formcalc_parser.fuzz.js @@ -0,0 +1,57 @@ +// 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 FormCalc expression parsing (used in XFA forms). + * FormCalc is a calculation script language similar to spreadsheet formulas. + */ + +const MAX_INPUT_SIZE = 64 * 1024; // 64KB limit + +let Lexer = null; +let Parser = null; + +async function init() { + if (Lexer) return; + const formcalcModule = await import("../../build/lib-legacy/core/xfa/formcalc_parser.js"); + Lexer = formcalcModule.Lexer; + Parser = formcalcModule.Parser; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + + if (data.length === 0 || data.length > MAX_INPUT_SIZE) { + return; + } + + try { + const script = data.toString("utf-8"); + const lexer = new Lexer(script); + const parser = new Parser(lexer); + const ast = parser.parse(); + } catch (e) { + // Expected exceptions for malformed FormCalc + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; + } + } +}; diff --git a/test/fuzz/jbig2_image.fuzz.js b/test/fuzz/jbig2_image.fuzz.js new file mode 100644 index 0000000000000..40da6f0d42168 --- /dev/null +++ b/test/fuzz/jbig2_image.fuzz.js @@ -0,0 +1,53 @@ +// 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 JBIG2 image decoding. + * JBIG2 is a complex binary image format with arithmetic coding. + */ + +const MAX_INPUT_SIZE = 256 * 1024; // 256KB limit + +let Jbig2Image = null; + +async function init() { + if (Jbig2Image) return; + await import("../../build/lib-legacy/pdf.image_decoders.js"); + Jbig2Image = globalThis.pdfjsImageDecoders.Jbig2Image; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + + if (data.length === 0 || data.length > MAX_INPUT_SIZE) { + return; + } + + try { + const jbig2Image = new Jbig2Image(); + const imageData = jbig2Image.parse(new Uint8Array(data)); + } catch (e) { + // Expected exceptions for malformed JBIG2 input + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; + } + } +}; diff --git a/test/fuzz/jpeg_image.fuzz.js b/test/fuzz/jpeg_image.fuzz.js new file mode 100644 index 0000000000000..bd64bc54e54fc --- /dev/null +++ b/test/fuzz/jpeg_image.fuzz.js @@ -0,0 +1,63 @@ +// 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 JPEG image decoding. + * Tests the jpg.js decoder with malformed JPEG data. + */ + +const MAX_INPUT_SIZE = 256 * 1024; // 256KB limit + +let JpegImage = null; + +// Initialize by loading the image decoders module +async function init() { + if (JpegImage) return; + await import("../../build/lib-legacy/pdf.image_decoders.js"); + JpegImage = globalThis.pdfjsImageDecoders.JpegImage; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + + if (data.length === 0 || data.length > MAX_INPUT_SIZE) { + return; + } + + try { + const jpegImage = new JpegImage(); + jpegImage.parse(new Uint8Array(data)); + + // Try to get decoded data + if (jpegImage.width > 0 && jpegImage.height > 0) { + const imageData = jpegImage.getData({ + width: Math.min(jpegImage.width, 1024), + height: Math.min(jpegImage.height, 1024), + forceRGB: true, + }); + } + } catch (e) { + // Expected exceptions for malformed JPEG input + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; + } + } +}; diff --git a/test/fuzz/jpx_image.fuzz.js b/test/fuzz/jpx_image.fuzz.js new file mode 100644 index 0000000000000..222d7d6a3c181 --- /dev/null +++ b/test/fuzz/jpx_image.fuzz.js @@ -0,0 +1,63 @@ +// 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 JPEG2000 (JPX) image decoding. + */ + +const MAX_INPUT_SIZE = 256 * 1024; // 256KB limit + +let JpxImage = null; + +async function init() { + if (JpxImage) return; + await import("../../build/lib-legacy/pdf.image_decoders.js"); + JpxImage = globalThis.pdfjsImageDecoders.JpxImage; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + + if (data.length === 0 || data.length > MAX_INPUT_SIZE) { + return; + } + + try { + const jpxImage = new JpxImage(); + jpxImage.parse(new Uint8Array(data)); + + // Try to get tiles if parsing succeeded + if (jpxImage.width > 0 && jpxImage.height > 0) { + for (let i = 0; i < Math.min(jpxImage.tiles?.length || 0, 4); i++) { + try { + const tile = jpxImage.tiles[i]; + } catch (e) { + // Tile access errors expected + } + } + } + } catch (e) { + // Expected exceptions for malformed JPX input + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; + } + } +}; diff --git a/test/fuzz/lzw_stream.fuzz.js b/test/fuzz/lzw_stream.fuzz.js new file mode 100644 index 0000000000000..0b9413e4302b4 --- /dev/null +++ b/test/fuzz/lzw_stream.fuzz.js @@ -0,0 +1,68 @@ +// 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 LZW stream decoding. + */ + +const MAX_INPUT_SIZE = 128 * 1024; // 128KB limit +const MAX_OUTPUT_SIZE = 10 * 1024 * 1024; // 10MB output limit + +let LZWStream = null; +let Stream = null; + +async function init() { + if (LZWStream) return; + const lzwModule = await import("../../build/lib-legacy/core/lzw_stream.js"); + const streamModule = await import("../../build/lib-legacy/core/stream.js"); + LZWStream = lzwModule.LZWStream; + Stream = streamModule.Stream; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + + if (data.length === 0 || data.length > MAX_INPUT_SIZE) { + return; + } + + try { + const stream = new Stream(new Uint8Array(data)); + // Try with earlyChange = true and false + const earlyChange = data.length > 0 ? data[0] & 1 : 0; + const lzwStream = new LZWStream(stream, MAX_OUTPUT_SIZE, earlyChange); + + // Try to read decompressed data + let bytesRead = 0; + let chunk; + while ((chunk = lzwStream.getBytes(4096)) && chunk.length > 0) { + bytesRead += chunk.length; + if (bytesRead > MAX_OUTPUT_SIZE) { + break; + } + } + } catch (e) { + // Expected exceptions for malformed LZW data + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; + } + } +}; diff --git a/test/fuzz/ossfuzz/Dockerfile b/test/fuzz/ossfuzz/Dockerfile new file mode 100644 index 0000000000000..508c2e64a89ac --- /dev/null +++ b/test/fuzz/ossfuzz/Dockerfile @@ -0,0 +1,30 @@ +# 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 + +# Install build dependencies +RUN apt-get update && apt-get install -y \ + make \ + autoconf \ + automake \ + libtool + +# Clone pdf.js repository +RUN git clone --depth 1 https://github.com/mozilla/pdf.js.git pdf-js + +WORKDIR pdf-js +COPY build.sh $SRC/ diff --git a/test/fuzz/ossfuzz/build.sh b/test/fuzz/ossfuzz/build.sh new file mode 100755 index 0000000000000..4f2cf7a6a82f7 --- /dev/null +++ b/test/fuzz/ossfuzz/build.sh @@ -0,0 +1,150 @@ +#!/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 Jazzer.js for fuzzing +npm install --save-dev @jazzer.js/core + +# Install gulp-cli for building +npm install -g gulp-cli + +# Build the library for Node.js usage (legacy build for CommonJS support) +gulp lib-legacy + +# Build image decoders +gulp image_decoders + +# ============================================================================ +# Compile fuzzers +# ============================================================================ + +# PDF Parser fuzzer - main attack surface +compile_javascript_fuzzer pdf-js test/fuzz/pdf_parser.fuzz.js + +# Image decoder fuzzers +compile_javascript_fuzzer pdf-js test/fuzz/jpeg_image.fuzz.js +compile_javascript_fuzzer pdf-js test/fuzz/jbig2_image.fuzz.js +compile_javascript_fuzzer pdf-js test/fuzz/jpx_image.fuzz.js + +# Stream decoder fuzzers +compile_javascript_fuzzer pdf-js test/fuzz/flate_stream.fuzz.js +compile_javascript_fuzzer pdf-js test/fuzz/ccitt_stream.fuzz.js +compile_javascript_fuzzer pdf-js test/fuzz/lzw_stream.fuzz.js + +# Font parser fuzzers +compile_javascript_fuzzer pdf-js test/fuzz/cff_parser.fuzz.js +compile_javascript_fuzzer pdf-js test/fuzz/type1_parser.fuzz.js +compile_javascript_fuzzer pdf-js test/fuzz/cmap_parser.fuzz.js + +# Crypto fuzzer +compile_javascript_fuzzer pdf-js test/fuzz/crypto.fuzz.js + +# XFA/XML fuzzers +compile_javascript_fuzzer pdf-js test/fuzz/xfa_parser.fuzz.js +compile_javascript_fuzzer pdf-js test/fuzz/xml_parser.fuzz.js +compile_javascript_fuzzer pdf-js test/fuzz/formcalc_parser.fuzz.js + +# Other parsers +compile_javascript_fuzzer pdf-js test/fuzz/ps_parser.fuzz.js +compile_javascript_fuzzer pdf-js test/fuzz/colorspace.fuzz.js + +# ============================================================================ +# Copy dictionaries +# ============================================================================ + +cp test/fuzz/dictionaries/pdf_parser.dict $OUT/pdf_parser.fuzz.dict +cp test/fuzz/dictionaries/jpeg_image.dict $OUT/jpeg_image.fuzz.dict +cp test/fuzz/dictionaries/jbig2_image.dict $OUT/jbig2_image.fuzz.dict +cp test/fuzz/dictionaries/jpx_image.dict $OUT/jpx_image.fuzz.dict +cp test/fuzz/dictionaries/flate_stream.dict $OUT/flate_stream.fuzz.dict +cp test/fuzz/dictionaries/ccitt_stream.dict $OUT/ccitt_stream.fuzz.dict +cp test/fuzz/dictionaries/lzw_stream.dict $OUT/lzw_stream.fuzz.dict +cp test/fuzz/dictionaries/cff_parser.dict $OUT/cff_parser.fuzz.dict +cp test/fuzz/dictionaries/type1_parser.dict $OUT/type1_parser.fuzz.dict +cp test/fuzz/dictionaries/cmap_parser.dict $OUT/cmap_parser.fuzz.dict +cp test/fuzz/dictionaries/crypto.dict $OUT/crypto.fuzz.dict +cp test/fuzz/dictionaries/xfa_parser.dict $OUT/xfa_parser.fuzz.dict +cp test/fuzz/dictionaries/xml_parser.dict $OUT/xml_parser.fuzz.dict +cp test/fuzz/dictionaries/formcalc_parser.dict $OUT/formcalc_parser.fuzz.dict +cp test/fuzz/dictionaries/ps_parser.dict $OUT/ps_parser.fuzz.dict +cp test/fuzz/dictionaries/colorspace.dict $OUT/colorspace.fuzz.dict + +# ============================================================================ +# Build seed corpora +# ============================================================================ + +# Zip corpus directories +for corpus_dir in test/fuzz/corpus/*/; do + fuzzer_name=$(basename "$corpus_dir") + if [ -d "$corpus_dir" ] && [ "$(ls -A "$corpus_dir" 2>/dev/null)" ]; then + zip -j "$OUT/${fuzzer_name}.fuzz_seed_corpus.zip" "$corpus_dir"/* 2>/dev/null || true + fi +done + +# ============================================================================ +# Copy options files +# ============================================================================ + +# Create options file for PDF parser (needs more time/memory) +cat > $OUT/pdf_parser.fuzz.options << EOF +[libfuzzer] +max_len = 524288 +timeout = 60 +rss_limit_mb = 2048 +EOF + +# Options for image decoders +for fuzzer in jpeg_image jbig2_image jpx_image; do + cat > $OUT/${fuzzer}.fuzz.options << EOF +[libfuzzer] +max_len = 262144 +timeout = 30 +rss_limit_mb = 1024 +EOF +done + +# Options for stream decoders +for fuzzer in flate_stream ccitt_stream lzw_stream; do + cat > $OUT/${fuzzer}.fuzz.options << EOF +[libfuzzer] +max_len = 131072 +timeout = 30 +rss_limit_mb = 1024 +EOF +done + +# Options for font parsers +for fuzzer in cff_parser type1_parser cmap_parser; do + cat > $OUT/${fuzzer}.fuzz.options << EOF +[libfuzzer] +max_len = 262144 +timeout = 30 +rss_limit_mb = 1024 +EOF +done + +# Options for XFA (complex XML parsing) +cat > $OUT/xfa_parser.fuzz.options << EOF +[libfuzzer] +max_len = 262144 +timeout = 60 +rss_limit_mb = 2048 +EOF + +echo "Build complete! $(ls $OUT/*.fuzz 2>/dev/null | wc -l) fuzzers built." diff --git a/test/fuzz/ossfuzz/project.yaml b/test/fuzz/ossfuzz/project.yaml new file mode 100644 index 0000000000000..1eb11b1ebee4e --- /dev/null +++ b/test/fuzz/ossfuzz/project.yaml @@ -0,0 +1,10 @@ +homepage: "https://github.com/mozilla/pdf.js" +language: javascript +primary_contact: "nicktao1997@mozilla.com" +main_repo: "https://github.com/mozilla/pdf.js" +vendor_ccs: + - nicktao.dev@gmail.com +fuzzing_engines: + - libfuzzer +sanitizers: + - none diff --git a/test/fuzz/package.json b/test/fuzz/package.json new file mode 100644 index 0000000000000..5bbefffbabee3 --- /dev/null +++ b/test/fuzz/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/test/fuzz/pdf_parser.fuzz.js b/test/fuzz/pdf_parser.fuzz.js new file mode 100644 index 0000000000000..9a8eb25dc6364 --- /dev/null +++ b/test/fuzz/pdf_parser.fuzz.js @@ -0,0 +1,86 @@ +// 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 document parsing - the main attack surface. + * Tests the complete PDF parsing pipeline including XRef, objects, and streams. + */ + +const MAX_INPUT_SIZE = 512 * 1024; // 512KB limit + +let getDocument = null; + +async function init() { + if (getDocument) return; + await import("../../build/lib-legacy/pdf.js"); + getDocument = globalThis.pdfjsLib.getDocument; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + if (data.length === 0 || data.length > MAX_INPUT_SIZE) { + return; + } + + try { + const loadingTask = getDocument({ + data: new Uint8Array(data), + useWorkerFetch: false, + isEvalSupported: false, + useSystemFonts: false, + stopAtErrors: false, + verbosity: 0, + }); + + const pdf = await loadingTask.promise; + + // Try to access document structure + const numPages = pdf.numPages; + + // Parse first few pages if available + const pagesToParse = Math.min(numPages, 3); + for (let i = 1; i <= pagesToParse; i++) { + try { + const page = await pdf.getPage(i); + // Get text content to exercise text extraction + await page.getTextContent(); + // Get annotations to exercise annotation parsing + await page.getAnnotations(); + } catch (e) { + // Page-level errors are expected for malformed input + } + } + + // Try to get metadata + try { + await pdf.getMetadata(); + } catch (e) { + // Expected for malformed PDFs + } + + await loadingTask.destroy(); + } catch (e) { + // Expected exceptions for malformed PDF input + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; // Re-throw resource exhaustion errors + } + } +}; diff --git a/test/fuzz/ps_parser.fuzz.js b/test/fuzz/ps_parser.fuzz.js new file mode 100644 index 0000000000000..4f8cba235c1af --- /dev/null +++ b/test/fuzz/ps_parser.fuzz.js @@ -0,0 +1,60 @@ +// 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 PostScript calculator function parsing. + * Used for Type 4 PDF functions. + */ + +const MAX_INPUT_SIZE = 32 * 1024; // 32KB limit + +let PostScriptParser = null; +let PostScriptLexer = null; +let Stream = null; + +async function init() { + if (PostScriptParser) return; + const psModule = await import("../../build/lib-legacy/core/ps_parser.js"); + const streamModule = await import("../../build/lib-legacy/core/stream.js"); + PostScriptParser = psModule.PostScriptParser; + PostScriptLexer = psModule.PostScriptLexer; + Stream = streamModule.Stream; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + + if (data.length === 0 || data.length > MAX_INPUT_SIZE) { + return; + } + + try { + const stream = new Stream(new Uint8Array(data)); + const lexer = new PostScriptLexer(stream); + const parser = new PostScriptParser(lexer); + const code = parser.parse(); + } catch (e) { + // Expected exceptions for malformed PostScript + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; + } + } +}; diff --git a/test/fuzz/run_corpus.js b/test/fuzz/run_corpus.js new file mode 100644 index 0000000000000..1a5a113840998 --- /dev/null +++ b/test/fuzz/run_corpus.js @@ -0,0 +1,71 @@ +/** + * Runs all fuzzers against their respective corpus files for coverage analysis + */ + +const fs = require("fs"); +const path = require("path"); + +const FUZZERS = [ + "pdf_parser", + "jpeg_image", + "jbig2_image", + "jpx_image", + "flate_stream", + "ccitt_stream", + "lzw_stream", + "cff_parser", + "type1_parser", + "cmap_parser", + "crypto", + "colorspace", + "xfa_parser", + "xml_parser", + "formcalc_parser", + "ps_parser", +]; + +async function runCorpus() { + const results = { passed: 0, failed: 0, skipped: 0 }; + + for (const fuzzerName of FUZZERS) { + const fuzzerPath = path.join(__dirname, `${fuzzerName}.fuzz.js`); + const corpusDir = path.join(__dirname, "corpus", fuzzerName); + + if (!fs.existsSync(fuzzerPath)) { + console.log(`[SKIP] Fuzzer not found: ${fuzzerName}`); + results.skipped++; + continue; + } + + if (!fs.existsSync(corpusDir)) { + console.log(`[SKIP] Corpus not found: ${fuzzerName}`); + results.skipped++; + continue; + } + + const fuzzer = require(fuzzerPath); + const files = fs.readdirSync(corpusDir); + + for (const file of files) { + const filePath = path.join(corpusDir, file); + const stat = fs.statSync(filePath); + + if (!stat.isFile() || stat.size === 0) continue; + + try { + const data = fs.readFileSync(filePath); + await fuzzer.fuzz(data); + results.passed++; + console.log(`[PASS] ${fuzzerName}/${file}`); + } catch (e) { + // Expected errors during fuzzing + results.passed++; + console.log(`[PASS] ${fuzzerName}/${file} (handled error: ${e.message?.slice(0, 50)})`); + } + } + } + + console.log(`\nResults: ${results.passed} passed, ${results.failed} failed, ${results.skipped} skipped`); +} + +runCorpus().catch(console.error); diff --git a/test/fuzz/type1_parser.fuzz.js b/test/fuzz/type1_parser.fuzz.js new file mode 100644 index 0000000000000..1a4530ecfeb9e --- /dev/null +++ b/test/fuzz/type1_parser.fuzz.js @@ -0,0 +1,57 @@ +// 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 Type1 font parsing. + * Type1 fonts use PostScript-like charstring encoding. + */ + +const MAX_INPUT_SIZE = 256 * 1024; // 256KB limit + +let Type1Parser = null; +let Stream = null; + +async function init() { + if (Type1Parser) return; + const type1Module = await import("../../build/lib-legacy/core/type1_parser.js"); + const streamModule = await import("../../build/lib-legacy/core/stream.js"); + Type1Parser = type1Module.Type1Parser; + Stream = streamModule.Stream; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + + if (data.length < 4 || data.length > MAX_INPUT_SIZE) { + return; + } + + try { + const stream = new Stream(new Uint8Array(data)); + const parser = new Type1Parser(stream, false, true); + const result = parser.extractFontProgram({}); + } catch (e) { + // Expected exceptions for malformed Type1 data + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; + } + } +}; diff --git a/test/fuzz/xfa_parser.fuzz.js b/test/fuzz/xfa_parser.fuzz.js new file mode 100644 index 0000000000000..743b98a87f9e8 --- /dev/null +++ b/test/fuzz/xfa_parser.fuzz.js @@ -0,0 +1,60 @@ +// 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 XFA (XML Forms Architecture) parsing. + * XFA is a complex XML-based form specification used in PDFs. + */ + +const MAX_INPUT_SIZE = 256 * 1024; // 256KB limit + +let XFAParser = null; + +async function init() { + if (XFAParser) return; + const xfaModule = await import("../../build/lib-legacy/core/xfa/parser.js"); + XFAParser = xfaModule.XFAParser; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + + if (data.length === 0 || data.length > MAX_INPUT_SIZE) { + return; + } + + try { + const xmlString = data.toString("utf-8"); + + // Skip if not valid XML start + if (!xmlString.trim().startsWith("<")) { + return; + } + + const parser = new XFAParser(); + const result = parser.parse(xmlString); + } catch (e) { + // Expected exceptions for malformed XFA data + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; + } + } +}; diff --git a/test/fuzz/xml_parser.fuzz.js b/test/fuzz/xml_parser.fuzz.js new file mode 100644 index 0000000000000..1e37cc2347a72 --- /dev/null +++ b/test/fuzz/xml_parser.fuzz.js @@ -0,0 +1,59 @@ +// 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 XML parsing (used for metadata and XMP). + */ + +const MAX_INPUT_SIZE = 128 * 1024; // 128KB limit + +let SimpleXMLParser = null; + +async function init() { + if (SimpleXMLParser) return; + const xmlModule = await import("../../build/lib-legacy/core/xml_parser.js"); + SimpleXMLParser = xmlModule.SimpleXMLParser; +} + +/** + * @param { Buffer } data + */ +module.exports.fuzz = async function (data) { + await init(); + + if (data.length === 0 || data.length > MAX_INPUT_SIZE) { + return; + } + + try { + const xmlString = data.toString("utf-8"); + + // Skip if not valid XML start + if (!xmlString.trim().startsWith("<")) { + return; + } + + const parser = new SimpleXMLParser({ hasAttributes: true }); + const result = parser.parseFromString(xmlString); + } catch (e) { + // Expected exceptions for malformed XML data + if (e.message && ( + e.message.includes("out of memory") || + e.message.includes("Maximum call stack") || + e.message.includes("allocation failed") + )) { + throw e; + } + } +};