From 4f4ce5aaa4e22f6af1f6556c96964afd720a88a4 Mon Sep 17 00:00:00 2001 From: Bailey Capuano Date: Tue, 5 Mar 2024 11:37:41 -0700 Subject: [PATCH 01/22] Pushing progress --- fuzzing/build.sh | 8 +++++ fuzzing/corpus/simple1.pdf | Bin 0 -> 850 bytes fuzzing/fuzz_extraction.py | 68 +++++++++++++++++++++++++++++++++++++ fuzzing/fuzz_helpers.py | 46 +++++++++++++++++++++++++ setup.py | 2 +- 5 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 fuzzing/build.sh create mode 100644 fuzzing/corpus/simple1.pdf create mode 100644 fuzzing/fuzz_extraction.py create mode 100644 fuzzing/fuzz_helpers.py diff --git a/fuzzing/build.sh b/fuzzing/build.sh new file mode 100644 index 00000000..d6762144 --- /dev/null +++ b/fuzzing/build.sh @@ -0,0 +1,8 @@ +cd "$SRC"/pdfminer.six +pip3 install .[dev] + +# Build fuzzers in $OUT +for fuzzer in $(find dev/fuzzing -name 'fuzz_*.py');do + compile_python_fuzzer "$fuzzer" +done +zip -q $OUT/pdfminer_fuzzer_seed_corpus.zip $SRC/corpus/* diff --git a/fuzzing/corpus/simple1.pdf b/fuzzing/corpus/simple1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0437ee3270264dd90b3326860fe1088f5bc5ef30 GIT binary patch literal 850 zcmaJ=OK*Ze5bk+@#avAEU}336n-C8^NYj@FNqR6IR@hPuvJEVK{rb-E(rVKXV0PyF z=Dio4<;?B#%K_tHg4*tw<1jG%uQv(CRA`Z?2+xZ`Cvhrsun^^;Vksg#U6rTtn8`FG zE?G}}G)&}7Rgr2i*#S@d6MX3y!S`{P!x{z@0X8k0AF;{y2fNHJlNhQ>4~$0{#$uvA z(VvNr%`F(-Shd$wBQ%F=3WQWo=Bmg7ERGt1g=Q*PNey;o2g6n9*>OPR*!+{_Y&cOW*(CekV}HhOTUcGM$Mykr`CCV- bytes: + return self.ConsumeBytes(self.ConsumeIntInRange(0, self.remaining_bytes())) + + def ConsumeRandomString(self) -> str: + return self.ConsumeUnicodeNoSurrogates(self.ConsumeIntInRange(0, self.remaining_bytes())) + + def ConsumeRemainingString(self) -> str: + return self.ConsumeUnicodeNoSurrogates(self.remaining_bytes()) + + def ConsumeRemainingBytes(self) -> bytes: + return self.ConsumeBytes(self.remaining_bytes()) + + @contextlib.contextmanager + def ConsumeMemoryFile(self, all_data: bool = False, as_bytes: bool = True) -> io.BytesIO: + if all_data: + file_data = self.ConsumeRemainingBytes() if as_bytes else self.ConsumeRemainingString() + else: + file_data = self.ConsumeRandomBytes() if as_bytes else self.ConsumeRandomString() + + file = io.BytesIO(file_data) if as_bytes else io.StringIO(file_data) + yield file + file.close() + + @contextlib.contextmanager + def ConsumeTemporaryFile(self, suffix: str, all_data: bool = False, as_bytes: bool = True) -> str: + if all_data: + file_data = self.ConsumeRemainingBytes() if as_bytes else self.ConsumeRemainingString() + else: + file_data = self.ConsumeRandomBytes() if as_bytes else self.ConsumeRandomString() + + mode = 'w+b' if as_bytes else 'w+' + tfile = tempfile.NamedTemporaryFile(mode=mode, suffix=suffix) + tfile.write(file_data) + tfile.seek(0) + tfile.flush() + yield tfile.name + tfile.close() + diff --git a/setup.py b/setup.py index 84e5ceea..62ad970c 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ 'importlib_metadata; python_version < "3.8"', ], extras_require={ - "dev": ["pytest", "nox", "black", "mypy == 0.931"], + "dev": ["pytest", "nox", "black", "mypy == 0.931", "atheris"], "docs": ["sphinx", "sphinx-argparse"], "image": ["Pillow"], }, From aa730143dcd423e322a9be67d13c7fc5a9bc3191 Mon Sep 17 00:00:00 2001 From: bcapuano Date: Sun, 10 Mar 2024 15:51:53 -0400 Subject: [PATCH 02/22] Initial fuzzing integration --- fuzzing/build.sh | 6 ++- fuzzing/corpus/simple1.pdf | Bin 850 -> 849 bytes fuzzing/corpus/simple2.pdf | Bin 0 -> 1174 bytes fuzzing/corpus/simple3.pdf | Bin 0 -> 1051 bytes fuzzing/corpus/simple4.pdf | Bin 0 -> 33297 bytes fuzzing/corpus/simple5.pdf | Bin 0 -> 74352 bytes fuzzing/extract_text_fuzzer.py | 45 +++++++++++++++++ fuzzing/extract_text_to_fp_fuzzer.py | 63 ++++++++++++++++++++++++ fuzzing/fuzz_extraction.py | 68 -------------------------- fuzzing/page_extraction_fuzzer.py | 44 +++++++++++++++++ fuzzing/pdf_utils.py | 69 +++++++++++++++++++++++++++ 11 files changed, 225 insertions(+), 70 deletions(-) create mode 100644 fuzzing/corpus/simple2.pdf create mode 100644 fuzzing/corpus/simple3.pdf create mode 100644 fuzzing/corpus/simple4.pdf create mode 100644 fuzzing/corpus/simple5.pdf create mode 100644 fuzzing/extract_text_fuzzer.py create mode 100644 fuzzing/extract_text_to_fp_fuzzer.py delete mode 100644 fuzzing/fuzz_extraction.py create mode 100755 fuzzing/page_extraction_fuzzer.py create mode 100644 fuzzing/pdf_utils.py diff --git a/fuzzing/build.sh b/fuzzing/build.sh index d6762144..840332b4 100644 --- a/fuzzing/build.sh +++ b/fuzzing/build.sh @@ -2,7 +2,9 @@ cd "$SRC"/pdfminer.six pip3 install .[dev] # Build fuzzers in $OUT -for fuzzer in $(find dev/fuzzing -name 'fuzz_*.py');do +for fuzzer in $(find fuzzing -name '*_fuzzer.py');do compile_python_fuzzer "$fuzzer" + base_name=$(basename "$fuzzer") + base_name_no_ext=${base_name%.*} + zip -q $OUT/"$base_name_no_ext".zip $SRC/corpus/* done -zip -q $OUT/pdfminer_fuzzer_seed_corpus.zip $SRC/corpus/* diff --git a/fuzzing/corpus/simple1.pdf b/fuzzing/corpus/simple1.pdf index 0437ee3270264dd90b3326860fe1088f5bc5ef30..77b8623bb637cbeaa79296e58c7fa2cc8eefa627 100644 GIT binary patch delta 8 Pcmcb_c9Cr(V<0mC4>AI_ delta 9 Qcmcb}c8QIVVM8D@01z$$wEzGB diff --git a/fuzzing/corpus/simple2.pdf b/fuzzing/corpus/simple2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9619ffe6081e52d86b9af1cbb2e889ed3c210839 GIT binary patch literal 1174 zcmZux%Wm5+5WMp%_Trl>OR{CvfRRIzCWod-VCQD|Kuar$H7yzxRVV%W?o#qI6+nQG znc3MTSA)05r*Ba(5fOx7HowJuE@1Tjxkng1NGG)^Y5m$dt!iu_Ce(s9-egIuv0vTY z39NJG^68Dnkx85f)7B0`amF+M2JeLl{8Qx(tR@^_ed0zJTt4~_*L$-_fjV`!#055{wHYNgpHqs~WJ`1~(W(_ z%o4^l&Z69j0X$lH00|o{vn_D#puuuS;fByQsxHA*2sswA)vh}~sN7Y7h>{Ru8aqE5 z(@cxySd&G4+rV@8?Bv;c60g{@B&(C`FZ{n73jQ8lzR`k=_?u>wwqhA|L0RqQ%U~y3_~< zMU|Bhu@A76?Z()glP{FkwDjj%m6fAHw@Aec=#Klbc=qvfD2xTV7qdmkj5bz;0bO8_ zCcto8671!q;n6JLV`EBpOoQ%$2o}Zt*=W|V-8++=#>sckN2XQ_Vpu%W zGKEsGJdd59aeXfbpJZagE!ID-zS;O)@*`Z0sD;eiNn2N;T85Mp1vNaCBXw4F8&7SD2R2psfQ(3CNNXDqojB&vKn+5k&!QjX1llTX$7(>GV literal 0 HcmV?d00001 diff --git a/fuzzing/corpus/simple3.pdf b/fuzzing/corpus/simple3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8c4f6487c808d2d9f867cbe0eeb57950dbdb0b1c GIT binary patch literal 1051 zcma)5+isgc5PjdT7*)6;m0T`$Y*(@()i*V5T1ObQ4{07YuqH&nTCk*XzrJUH6vypD zL7?54IWv3C%nq)X>!J5{Bs_9S-#v)gOpp^E_KKW^G&0i(_M6&dX`w3e5f#92EfehC zHM@%op^BKX>^;fxj09$(>%x#L`gq2l#5ai%{5g#)x}gzQpxZxa?+DGlf1sPwl?tWW zy>3$udN@p^`-}izsw!XYZC5+ z{au$?+ym&y(1fl+Zg@wbYd!13Om86Ba*YX6PX-EiUKZ-4RjecQ-qv@f88#j{4~DNY z$LOtjIhU1cka^swx6CSr|Sa4=QGbhoZeWEjPl`^IKdl*~|f`+W27F9x9{q%VMY7d21bk zN>a#sAo~OEl{#zVk!@4Ps$}l=C%Kn}*L$}0exIqF#~#x0!^7D8ZjW>krj%)>N^0-< XHvOe&3POR_07A5Yg9n4vW-WdLqxKk_ literal 0 HcmV?d00001 diff --git a/fuzzing/corpus/simple4.pdf b/fuzzing/corpus/simple4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..14b6fc5eef447b7d1f1352a7abd2a3c23696a0be GIT binary patch literal 33297 zcmcGz19WB4wl)|i729?ywr$&}*tS`*ZQD*NM#Z*m+x$~??|psW``_yxqxy^)cEjg2EdJ>6dsX+3)jacg6nFEf8g zBSZWzF(V!xT4^IkJ;N`X_zWz61y#(9T#W4H?2U|#?2W7q{`g@1v%$jy18HP!_&1h6 zUjI{2e}kbFv~jZja!4y_X6T@a&-h168~@++{;>Wxy{}BZ96A0o6$K*)8z=iOw_kw@ zyE=+0I_fzZebJ(d%=pZIEPhdJ_-ucuui!;&tR25LMd@!r3C)*CHRjo@jqdGWo~GuCt%~M`DKg_pPhvcpP7kH8~-Z}YsasE9PpX` z;m_X2$@a_1-|CD0So+t1H`zBSogi4Q4^cIe=io#R6t z{cQb%Fdfb|)}JpdM9m^BRs_TXVle>u6m~)ZBtB8tF5X|hJ&8ge@_f*FBUYaRRAgQi z1j@0k$CD1n-<{j=w@E3x5mFpzV*!Ke{s6Sh)(wZ+e0PXCy+sPS!u_5SWf)iz6J4)R zSmfaw@dGSRy$kK~X76|bdW$piCyY@48RYoLcu|L>*zbMF61=?^4m6`k}Q|1^uz7smgZ zlF_p=`hp3qfS!ZVUkL$0Az@)*NyYQBHc^bB-g>V}S{UoG<&I{zN$AI1MI&i~8s zUnKtx^1lT3g$ol0d`1RZ@vpWwGvK#2u{6S`qvdxn_|r42%yeJS`v*fjj zYGyh{{67xx=^2>l{lRu^TLaz}6KEvP6{P%SKH0Xay_rE(!LH_@ImhAtoWaemT zME*6-_?;Y0ZS2VfjI8k$ZOx4A9lm&iUmf9SW@9b%)idNm91L^}baYH~Z1i*tEDWra zbo69&bYx#*(l&4~`;p;I5a0I9Vzz2}~qFn%t zzW9GAGXU#<@{PY%_Fwz5Uy{auHI2Sji~uYE%>N4TE9(EVX8*mw^#7??f3PmAZ?5QQ zMJt0(|8=^50E*AX_C@?p(}j_p{g1tWHKA)prlPb(FCTmd)JHITQ}MWUga|x;*$iPA zdM@~}UgRvgR9&5Q_s8qR!EZ3kT-06$8=j5M)Ug{tw(eItTYlRueTd#%Szr9%!vOfL zR^+Shd+=_LsnfP@oGbEf_B(b0KyMoe!)IXomo3Eu)4qkIML!rQHQOYNRqxDLP?5vj zRFafBaZ~$L%WLzjvz}}}YUeFa08P=Ym67XTs}!N_VW#ilffB#Y^=4H>JKnT?$w99M zL8taEzQMym*h&KK-~p|903AgqIz9Mzv^GstKS|Hmd>^jVYBtk1)d+2Wm=QTqA+k=dd%9z~59iNX7Z)+qx@oPB{X6 zGSkG|_?|>!7t|xK5x77<9KxTbW`wdp`jKFWe58Fmt5b@UUPdP?uDIQTjSz`qwxkfG z!F)9uI{}t8z#uRG8-e&55UXXMI|0=!wayKDAG2IX)y;i*`S2v!pmd#~f3)i7y+Mh} zO%wY11S>@juE2jgApcI4zg?w?&rHYqAJ3oH*Z-G`iS5sH`oF)J*#ETj|9mkr{+R)P zE+$4sZTx@xt?=(-{eOld0}B%)-9O)a^!RM-bj%F@8J=gJ;JQl6D-Z0CGNV$YjPV@9 z#ADEc0;xX%a*2Hn@dI^$ph@Q({lOqQAkabi^VJr@^76`eXp)9~5i5>X7If6wsw#}E z)SOj?C2qJ6J00+^C||2jtFk|NZEnVHGaeH>UcB;&BNzwHo~CL?;t={3H$7W*!FQiu zw_I}#`+nucJ*r3>dUn$cC{6ZJw7ggO7#b59ym`)*RiyryZ!q3M5}U*hetS#Xm*nd{|bopE?=ehD$mMG1RlWIfM z1-Q?Bdzz%8?QzkxACc`0HG_q!G+y1dJ;myPzUYB|T3=wc9ao4$(}b|wB9LICp|zMm z*KG0KAo57Cc`_vh>i5<=?W1;wO_bFUE7g48&-KscG!xJ+7We+X-@#EVgPzuyA%@V3 z=olv$YMi^#sm(Y%j;5MphZ>TZR2$@6RXP<}$LgRBy=PR(Rss`z=Penf9K2n~Eu`Ug`{&zn@7G2!?*-YN9O z`{N$9vEYueHbM?#JLViA##)Iddskr|% z`(L%rKjjsP#G>Co&$Pw(DOOXWw14;g$a@g-UYr
a?Jk~VU(q}Lo#smrvK72y}@ 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 bool: + """ + Performs basic checks on the incoming byte-stream to determine if it is worth passing the input to the library + :return: Whether the byte-stream passes the basic checks + """ + if not data.startswith(PDFValidator._PDF_MAGIC_BYTES): + return False + if b'/Root' not in data: + return False + + return True + + @staticmethod + @atheris.instrument_func + def generate_layout_parameters(fdp: atheris.FuzzedDataProvider) -> Optional[LAParams]: + return LAParams( + line_overlap=fdp.ConsumeFloat(), + char_margin=fdp.ConsumeFloat(), + line_margin=fdp.ConsumeFloat(), + word_margin=fdp.ConsumeFloat(), + boxes_flow=fdp.ConsumeFloatInRange(-1.0, 1.0) if fdp.ConsumeBool() else None, + detect_vertical=fdp.ConsumeBool(), + all_texts=fdp.ConsumeBool() + ) if fdp.ConsumeBool() else None + + @staticmethod + def should_ignore_error(e: Exception) -> bool: + """ + Determines if the given raised exception is an exception explicitly raised by pdfminer + :param e: The exception to check + :return: Whether the exception should be ignored or re-thrown + """ + return isinstance(e, PSException) or any(em_ss in str(e) for em_ss in _EXPLICIT_EXCEPTION_MESSAGES) From 4063d56e6206c6a6707fe86232c63c156c2b1bba Mon Sep 17 00:00:00 2001 From: bcapuano Date: Sun, 10 Mar 2024 15:52:20 -0400 Subject: [PATCH 03/22] Two proposed simple bug-fixes that were preventing fuzzing from advancing --- pdfminer/pdfdocument.py | 2 +- pdfminer/pdfparser.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pdfminer/pdfdocument.py b/pdfminer/pdfdocument.py index 258e9473..30662d48 100644 --- a/pdfminer/pdfdocument.py +++ b/pdfminer/pdfdocument.py @@ -977,7 +977,7 @@ def find_xref(self, parser: PDFParser) -> int: else: raise PDFNoValidXRef("Unexpected EOF") log.debug("xref found: pos=%r", prev) - assert prev is not None + assert prev is not None and prev.isdigit() return int(prev) # read xref table diff --git a/pdfminer/pdfparser.py b/pdfminer/pdfparser.py index 992d8840..d988da3b 100644 --- a/pdfminer/pdfparser.py +++ b/pdfminer/pdfparser.py @@ -80,7 +80,7 @@ def do_keyword(self, pos: int, token: PSKeyword) -> None: assert self.doc is not None obj = PDFObjRef(self.doc, objid, genno) self.push((pos, obj)) - except PSSyntaxError: + except (TypeError, PSSyntaxError): pass elif token is self.KEYWORD_STREAM: # stream object @@ -163,7 +163,7 @@ def do_keyword(self, pos: int, token: PSKeyword) -> None: (objid, genno) = (int(objid), int(genno)) # type: ignore[arg-type] obj = PDFObjRef(self.doc, objid, genno) self.push((pos, obj)) - except PSSyntaxError: + except (TypeError, PSSyntaxError): pass return elif token in (self.KEYWORD_OBJ, self.KEYWORD_ENDOBJ): From 0f41ba6ec8f4365a6aa2c928f2603491d1c2a27a Mon Sep 17 00:00:00 2001 From: bcapuano Date: Sun, 10 Mar 2024 15:54:41 -0400 Subject: [PATCH 04/22] Fixed build script Updated build Updated build Updated build --- fuzzing/build.sh | 2 +- fuzzing/page_extraction_fuzzer.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fuzzing/build.sh b/fuzzing/build.sh index 840332b4..d2f8f7f1 100644 --- a/fuzzing/build.sh +++ b/fuzzing/build.sh @@ -3,7 +3,7 @@ pip3 install .[dev] # Build fuzzers in $OUT for fuzzer in $(find fuzzing -name '*_fuzzer.py');do - compile_python_fuzzer "$fuzzer" + compile_python_fuzzer "$fuzzer" --collect-all charset_normalizer --hidden-import=_cffi_backend base_name=$(basename "$fuzzer") base_name_no_ext=${base_name%.*} zip -q $OUT/"$base_name_no_ext".zip $SRC/corpus/* diff --git a/fuzzing/page_extraction_fuzzer.py b/fuzzing/page_extraction_fuzzer.py index 6213acf7..bc119ea9 100755 --- a/fuzzing/page_extraction_fuzzer.py +++ b/fuzzing/page_extraction_fuzzer.py @@ -18,7 +18,7 @@ def TestOneInput(data: bytes): fdp = EnhancedFuzzedDataProvider(data) try: - with (fdp.ConsumeMemoryFile() as f): + with fdp.ConsumeMemoryFile() as f: max_pages = fdp.ConsumeIntInRange(0, 1000) list(extract_pages( f, From 2df272e5525967f72f563b01d9b862d352764a42 Mon Sep 17 00:00:00 2001 From: bcapuano Date: Sun, 10 Mar 2024 16:34:45 -0400 Subject: [PATCH 05/22] Added CIFuzz workflow --- .github/workflows/cifuzz.yml | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/cifuzz.yml diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml new file mode 100644 index 00000000..60c4754a --- /dev/null +++ b/.github/workflows/cifuzz.yml @@ -0,0 +1,39 @@ +name: CIFuzz +on: + push: + branches: + - master + pull_request: +permissions: {} +jobs: + Fuzzing: + runs-on: ubuntu-latest + permissions: + security-events: write + steps: + - name: Build Fuzzers + id: build + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'pdfminersix' + language: python + - name: Run Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'pdfminersix' + language: python + fuzz-seconds: 800 + output-sarif: true + - name: Upload Crash + uses: actions/upload-artifact@v3 + if: failure() && steps.build.outcome == 'success' + with: + name: artifacts + path: ./out/artifacts + - name: Upload Sarif + if: always() && steps.build.outcome == 'success' + uses: github/codeql-action/upload-sarif@v2 + with: + # Path to SARIF file relative to the root of the repository + sarif_file: cifuzz-sarif/results.sarif + checkout_path: cifuzz-sarif From 9dc494971d58f7a143fe63c75c3f6fb770bbd222 Mon Sep 17 00:00:00 2001 From: bcapuano Date: Sun, 10 Mar 2024 16:40:22 -0400 Subject: [PATCH 06/22] Removed atheris from Python 3.12 dependencies --- setup.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index 62ad970c..2061c6b3 100644 --- a/setup.py +++ b/setup.py @@ -5,6 +5,16 @@ with open(root_dir / "README.md", "rt") as f: readme = f.read() +extras_require = { + "dev": ["pytest", "nox", "black", "mypy == 0.931"], + "docs": ["sphinx", "sphinx-argparse"], + "image": ["Pillow"], +} + +if sys.version_info < (3, 12): + # There is currently no atheris support for Python 3.12 + extras_require["dev"].append("atheris") + setup( name="pdfminer.six", setuptools_git_versioning={ @@ -19,11 +29,7 @@ 'typing_extensions; python_version < "3.8"', 'importlib_metadata; python_version < "3.8"', ], - extras_require={ - "dev": ["pytest", "nox", "black", "mypy == 0.931", "atheris"], - "docs": ["sphinx", "sphinx-argparse"], - "image": ["Pillow"], - }, + extras_require=extras_require, description="PDF parser and analyzer", long_description=readme, long_description_content_type="text/markdown", From ef620c3df5d88c143f80d49498537b9dcf593737 Mon Sep 17 00:00:00 2001 From: bcapuano Date: Sun, 10 Mar 2024 16:41:53 -0400 Subject: [PATCH 07/22] Removed atheris from Python 3.12 dependencies --- setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.py b/setup.py index 2061c6b3..83d999c0 100644 --- a/setup.py +++ b/setup.py @@ -1,3 +1,5 @@ +import sys + from pathlib import Path from setuptools import setup From db33a3864e25f8c21dce0967ed507eb22f9c497a Mon Sep 17 00:00:00 2001 From: bcapuano Date: Sun, 10 Mar 2024 16:46:12 -0400 Subject: [PATCH 08/22] Updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb994507..3be6e633 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added - Support for zipped jpeg's ([#938](https://github.com/pdfminer/pdfminer.six/pull/938)) +- Added fuzzing harnesses for integration into Google's OSS-Fuzz ### Fixed From 8cbc4f910d2e6297cefbe1f3f519216352715586 Mon Sep 17 00:00:00 2001 From: Bailey Capuano Date: Wed, 26 Jun 2024 19:29:40 -0600 Subject: [PATCH 09/22] Removed corpus files --- fuzzing/corpus/simple1.pdf | Bin 849 -> 0 bytes fuzzing/corpus/simple2.pdf | Bin 1174 -> 0 bytes fuzzing/corpus/simple3.pdf | Bin 1051 -> 0 bytes fuzzing/corpus/simple4.pdf | Bin 33297 -> 0 bytes fuzzing/corpus/simple5.pdf | Bin 74352 -> 0 bytes 5 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 fuzzing/corpus/simple1.pdf delete mode 100644 fuzzing/corpus/simple2.pdf delete mode 100644 fuzzing/corpus/simple3.pdf delete mode 100644 fuzzing/corpus/simple4.pdf delete mode 100644 fuzzing/corpus/simple5.pdf diff --git a/fuzzing/corpus/simple1.pdf b/fuzzing/corpus/simple1.pdf deleted file mode 100644 index 77b8623bb637cbeaa79296e58c7fa2cc8eefa627..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 849 zcmaJ=OK*Ze5WerPn2U)XEG(sH6XU@LY5LM2Ne{-u3R{Xnwt=O!{q>#UrPZb(!0gQT z&3ik`ncL@AHsfG|+V0qB#K7>s-X$1Qp+%x1JTD5J#Hq}|LX?M!rHJr!U7p5cCex6( zWIglIFp)D=MXJGMM?CS*@TFq}Kg3}UYp^K-Y+5!yVUz6-c9~r!F;tZv7*8^c#Y7#@ zpNWsdEg0NdwbxW5G>01sgj7%Fs>lK?jv9f5W-3@o4NheT!&T^cG(v&HfRups(0eS4 zd{v2o@hHvQ zYUVzzPu-e&k*M3$!8HzG=HfoegT{H)R%-j%;Atv2y;ZT*OR{CvfRRIzCWod-VCQD|Kuar$H7yzxRVV%W?o#qI6+nQG znc3MTSA)05r*Ba(5fOx7HowJuE@1Tjxkng1NGG)^Y5m$dt!iu_Ce(s9-egIuv0vTY z39NJG^68Dnkx85f)7B0`amF+M2JeLl{8Qx(tR@^_ed0zJTt4~_*L$-_fjV`!#055{wHYNgpHqs~WJ`1~(W(_ z%o4^l&Z69j0X$lH00|o{vn_D#puuuS;fByQsxHA*2sswA)vh}~sN7Y7h>{Ru8aqE5 z(@cxySd&G4+rV@8?Bv;c60g{@B&(C`FZ{n73jQ8lzR`k=_?u>wwqhA|L0RqQ%U~y3_~< zMU|Bhu@A76?Z()glP{FkwDjj%m6fAHw@Aec=#Klbc=qvfD2xTV7qdmkj5bz;0bO8_ zCcto8671!q;n6JLV`EBpOoQ%$2o}Zt*=W|V-8++=#>sckN2XQ_Vpu%W zGKEsGJdd59aeXfbpJZagE!ID-zS;O)@*`Z0sD;eiNn2N;T85Mp1vNaCBXw4F8&7SD2R2psfQ(3CNNXDqojB&vKn+5k&!QjX1llTX$7(>GV diff --git a/fuzzing/corpus/simple3.pdf b/fuzzing/corpus/simple3.pdf deleted file mode 100644 index 8c4f6487c808d2d9f867cbe0eeb57950dbdb0b1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1051 zcma)5+isgc5PjdT7*)6;m0T`$Y*(@()i*V5T1ObQ4{07YuqH&nTCk*XzrJUH6vypD zL7?54IWv3C%nq)X>!J5{Bs_9S-#v)gOpp^E_KKW^G&0i(_M6&dX`w3e5f#92EfehC zHM@%op^BKX>^;fxj09$(>%x#L`gq2l#5ai%{5g#)x}gzQpxZxa?+DGlf1sPwl?tWW zy>3$udN@p^`-}izsw!XYZC5+ z{au$?+ym&y(1fl+Zg@wbYd!13Om86Ba*YX6PX-EiUKZ-4RjecQ-qv@f88#j{4~DNY z$LOtjIhU1cka^swx6CSr|Sa4=QGbhoZeWEjPl`^IKdl*~|f`+W27F9x9{q%VMY7d21bk zN>a#sAo~OEl{#zVk!@4Ps$}l=C%Kn}*L$}0exIqF#~#x0!^7D8ZjW>krj%)>N^0-< XHvOe&3POR_07A5Yg9n4vW-WdLqxKk_ diff --git a/fuzzing/corpus/simple4.pdf b/fuzzing/corpus/simple4.pdf deleted file mode 100644 index 14b6fc5eef447b7d1f1352a7abd2a3c23696a0be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33297 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
a?Jk~VU(q}Lo#smrvK72y}@ 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 Date: Thu, 27 Jun 2024 18:17:16 +0200 Subject: [PATCH 10/22] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3be6e633..d62cb275 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added - Support for zipped jpeg's ([#938](https://github.com/pdfminer/pdfminer.six/pull/938)) -- Added fuzzing harnesses for integration into Google's OSS-Fuzz +- Fuzzing harnesses for integration into Google's OSS-Fuzz ([949](https://github.com/pdfminer/pdfminer.six/pull/949)) ### Fixed From ec70d62a9f6e1886490c78ea085a07f7c604105d Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Thu, 27 Jun 2024 18:18:31 +0200 Subject: [PATCH 11/22] Added fuzzing directory to noxfile.py --- fuzzing/extract_text_fuzzer.py | 2 +- fuzzing/extract_text_to_fp_fuzzer.py | 15 ++------- fuzzing/fuzz_helpers.py | 35 +++++++++++++++----- fuzzing/page_extraction_fuzzer.py | 16 +++++---- fuzzing/pdf_utils.py | 49 +++++++++++++++++----------- noxfile.py | 2 +- 6 files changed, 71 insertions(+), 48 deletions(-) diff --git a/fuzzing/extract_text_fuzzer.py b/fuzzing/extract_text_fuzzer.py index aa279664..9b270701 100644 --- a/fuzzing/extract_text_fuzzer.py +++ b/fuzzing/extract_text_fuzzer.py @@ -25,7 +25,7 @@ def TestOneInput(data: bytes): f, maxpages=max_pages, page_numbers=fdp.ConsumeIntList(fdp.ConsumeIntInRange(0, max_pages), 2), - laparams=PDFValidator.generate_layout_parameters(fdp) + laparams=PDFValidator.generate_layout_parameters(fdp), ) except (AssertionError, PSException): return -1 diff --git a/fuzzing/extract_text_to_fp_fuzzer.py b/fuzzing/extract_text_to_fp_fuzzer.py index 2ea19807..b6ee8ecd 100644 --- a/fuzzing/extract_text_to_fp_fuzzer.py +++ b/fuzzing/extract_text_to_fp_fuzzer.py @@ -10,17 +10,8 @@ from pdfminer.high_level import extract_text_to_fp from pdfminer.psparser import PSException -available_output_formats = [ - 'text', - 'html', - 'xml', - 'tag' -] -available_layout_modes = [ - 'exact', - 'normal', - 'loose' -] +available_output_formats = ["text", "html", "xml", "tag"] +available_layout_modes = ["exact", "normal", "loose"] def TestOneInput(data: bytes): @@ -43,7 +34,7 @@ def TestOneInput(data: bytes): scale=fdp.ConsumeFloatInRange(0.0, 2.0), rotation=fdp.ConsumeIntInRange(0, 360), layoutmode=fdp.PickValueInList(available_layout_modes), - strip_control=fdp.ConsumeBool() + strip_control=fdp.ConsumeBool(), ) except (AssertionError, PSException): return -1 diff --git a/fuzzing/fuzz_helpers.py b/fuzzing/fuzz_helpers.py index fd1bd529..b78ca7cc 100644 --- a/fuzzing/fuzz_helpers.py +++ b/fuzzing/fuzz_helpers.py @@ -10,7 +10,9 @@ def ConsumeRandomBytes(self) -> bytes: return self.ConsumeBytes(self.ConsumeIntInRange(0, self.remaining_bytes())) def ConsumeRandomString(self) -> str: - return self.ConsumeUnicodeNoSurrogates(self.ConsumeIntInRange(0, self.remaining_bytes())) + return self.ConsumeUnicodeNoSurrogates( + self.ConsumeIntInRange(0, self.remaining_bytes()) + ) def ConsumeRemainingString(self) -> str: return self.ConsumeUnicodeNoSurrogates(self.remaining_bytes()) @@ -19,28 +21,43 @@ def ConsumeRemainingBytes(self) -> bytes: return self.ConsumeBytes(self.remaining_bytes()) @contextlib.contextmanager - def ConsumeMemoryFile(self, all_data: bool = False, as_bytes: bool = True) -> io.BytesIO: + def ConsumeMemoryFile( + self, all_data: bool = False, as_bytes: bool = True + ) -> io.BytesIO: if all_data: - file_data = self.ConsumeRemainingBytes() if as_bytes else self.ConsumeRemainingString() + file_data = ( + self.ConsumeRemainingBytes() + if as_bytes + else self.ConsumeRemainingString() + ) else: - file_data = self.ConsumeRandomBytes() if as_bytes else self.ConsumeRandomString() + file_data = ( + self.ConsumeRandomBytes() if as_bytes else self.ConsumeRandomString() + ) file = io.BytesIO(file_data) if as_bytes else io.StringIO(file_data) yield file file.close() @contextlib.contextmanager - def ConsumeTemporaryFile(self, suffix: str, all_data: bool = False, as_bytes: bool = True) -> str: + def ConsumeTemporaryFile( + self, suffix: str, all_data: bool = False, as_bytes: bool = True + ) -> str: if all_data: - file_data = self.ConsumeRemainingBytes() if as_bytes else self.ConsumeRemainingString() + file_data = ( + self.ConsumeRemainingBytes() + if as_bytes + else self.ConsumeRemainingString() + ) else: - file_data = self.ConsumeRandomBytes() if as_bytes else self.ConsumeRandomString() + file_data = ( + self.ConsumeRandomBytes() if as_bytes else self.ConsumeRandomString() + ) - mode = 'w+b' if as_bytes else 'w+' + mode = "w+b" if as_bytes else "w+" tfile = tempfile.NamedTemporaryFile(mode=mode, suffix=suffix) tfile.write(file_data) tfile.seek(0) tfile.flush() yield tfile.name tfile.close() - diff --git a/fuzzing/page_extraction_fuzzer.py b/fuzzing/page_extraction_fuzzer.py index bc119ea9..7794d1ee 100755 --- a/fuzzing/page_extraction_fuzzer.py +++ b/fuzzing/page_extraction_fuzzer.py @@ -20,12 +20,16 @@ def TestOneInput(data: bytes): try: with fdp.ConsumeMemoryFile() as f: max_pages = fdp.ConsumeIntInRange(0, 1000) - list(extract_pages( - f, - maxpages=max_pages, - page_numbers=fdp.ConsumeIntList(fdp.ConsumeIntInRange(0, max_pages), 2), - laparams=PDFValidator.generate_layout_parameters(fdp) - )) + list( + extract_pages( + f, + maxpages=max_pages, + page_numbers=fdp.ConsumeIntList( + fdp.ConsumeIntInRange(0, max_pages), 2 + ), + laparams=PDFValidator.generate_layout_parameters(fdp), + ) + ) except (AssertionError, PSException): return -1 except Exception as e: diff --git a/fuzzing/pdf_utils.py b/fuzzing/pdf_utils.py index 501dbae3..b0ba450c 100644 --- a/fuzzing/pdf_utils.py +++ b/fuzzing/pdf_utils.py @@ -11,11 +11,11 @@ # List of all exception message substrings explicitly raised by pdfminer that do not inherit from PSException _EXPLICIT_EXCEPTION_MESSAGES = [ - 'Unsupported', - 'duplicate labels', - 'AcroForm', - 'SASLPrep', - 'Invalid' + "Unsupported", + "duplicate labels", + "AcroForm", + "SASLPrep", + "Invalid", ] @@ -23,14 +23,15 @@ def prepare_pdfminer_fuzzing(): """ Used to disable logging of the pdfminer module """ - logging.getLogger('pdfminer').setLevel(logging.CRITICAL) + logging.getLogger("pdfminer").setLevel(logging.CRITICAL) class PDFValidator: """ Custom mutator class for PDFs for more efficient fuzzing """ - _PDF_MAGIC_BYTES = b'%PDF-' + + _PDF_MAGIC_BYTES = b"%PDF-" @staticmethod @atheris.instrument_func @@ -41,23 +42,31 @@ def is_valid_byte_stream(data: bytes) -> bool: """ if not data.startswith(PDFValidator._PDF_MAGIC_BYTES): return False - if b'/Root' not in data: + if b"/Root" not in data: return False return True @staticmethod @atheris.instrument_func - def generate_layout_parameters(fdp: atheris.FuzzedDataProvider) -> Optional[LAParams]: - return LAParams( - line_overlap=fdp.ConsumeFloat(), - char_margin=fdp.ConsumeFloat(), - line_margin=fdp.ConsumeFloat(), - word_margin=fdp.ConsumeFloat(), - boxes_flow=fdp.ConsumeFloatInRange(-1.0, 1.0) if fdp.ConsumeBool() else None, - detect_vertical=fdp.ConsumeBool(), - all_texts=fdp.ConsumeBool() - ) if fdp.ConsumeBool() else None + def generate_layout_parameters( + fdp: atheris.FuzzedDataProvider, + ) -> Optional[LAParams]: + return ( + LAParams( + line_overlap=fdp.ConsumeFloat(), + char_margin=fdp.ConsumeFloat(), + line_margin=fdp.ConsumeFloat(), + word_margin=fdp.ConsumeFloat(), + boxes_flow=fdp.ConsumeFloatInRange(-1.0, 1.0) + if fdp.ConsumeBool() + else None, + detect_vertical=fdp.ConsumeBool(), + all_texts=fdp.ConsumeBool(), + ) + if fdp.ConsumeBool() + else None + ) @staticmethod def should_ignore_error(e: Exception) -> bool: @@ -66,4 +75,6 @@ def should_ignore_error(e: Exception) -> bool: :param e: The exception to check :return: Whether the exception should be ignored or re-thrown """ - return isinstance(e, PSException) or any(em_ss in str(e) for em_ss in _EXPLICIT_EXCEPTION_MESSAGES) + return isinstance(e, PSException) or any( + em_ss in str(e) for em_ss in _EXPLICIT_EXCEPTION_MESSAGES + ) diff --git a/noxfile.py b/noxfile.py index 52995e1b..5c9aca14 100644 --- a/noxfile.py +++ b/noxfile.py @@ -4,7 +4,7 @@ PYTHON_ALL_VERSIONS = ["3.8", "3.9", "3.10", "3.11", "3.12"] -PYTHON_MODULES = ["pdfminer", "tools", "tests", "noxfile.py", "setup.py"] +PYTHON_MODULES = ["fuzzing", "pdfminer", "tools", "tests", "noxfile.py", "setup.py"] @nox.session From c09559433998a7e9222248f86bfd7a53073c9238 Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Thu, 27 Jun 2024 18:24:37 +0200 Subject: [PATCH 12/22] Fix flake8 --- fuzzing/fuzz_helpers.py | 1 - fuzzing/pdf_utils.py | 8 ++++---- pdfminer/utils.py | 1 + 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fuzzing/fuzz_helpers.py b/fuzzing/fuzz_helpers.py index b78ca7cc..7c7e106f 100644 --- a/fuzzing/fuzz_helpers.py +++ b/fuzzing/fuzz_helpers.py @@ -2,7 +2,6 @@ import tempfile import atheris import contextlib -from typing import List, Set, Dict, Tuple, Any class EnhancedFuzzedDataProvider(atheris.FuzzedDataProvider): diff --git a/fuzzing/pdf_utils.py b/fuzzing/pdf_utils.py index b0ba450c..4220c77b 100644 --- a/fuzzing/pdf_utils.py +++ b/fuzzing/pdf_utils.py @@ -9,7 +9,8 @@ from pdfminer.layout import LAParams from pdfminer.psparser import PSException -# List of all exception message substrings explicitly raised by pdfminer that do not inherit from PSException +# List of all exception message substrings explicitly raised by pdfminer that do not +# inherit from PSException _EXPLICIT_EXCEPTION_MESSAGES = [ "Unsupported", "duplicate labels", @@ -36,8 +37,7 @@ class PDFValidator: @staticmethod @atheris.instrument_func def is_valid_byte_stream(data: bytes) -> bool: - """ - Performs basic checks on the incoming byte-stream to determine if it is worth passing the input to the library + """Quick check to see if this is worth of passing to atheris :return: Whether the byte-stream passes the basic checks """ if not data.startswith(PDFValidator._PDF_MAGIC_BYTES): @@ -71,7 +71,7 @@ def generate_layout_parameters( @staticmethod def should_ignore_error(e: Exception) -> bool: """ - Determines if the given raised exception is an exception explicitly raised by pdfminer + Determines if the given raised exception is explicitly raised by pdfminer :param e: The exception to check :return: Whether the exception should be ignored or re-thrown """ diff --git a/pdfminer/utils.py b/pdfminer/utils.py index 59cf5cd3..2255ce07 100644 --- a/pdfminer/utils.py +++ b/pdfminer/utils.py @@ -25,6 +25,7 @@ cast, ) + if TYPE_CHECKING: from .layout import LTComponent From a946a7e2bc52be07c79c4a1aab71480978f99d4f Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Thu, 27 Jun 2024 18:57:50 +0200 Subject: [PATCH 13/22] Fix mypy --- fuzzing/extract_text_fuzzer.py | 16 +++----- fuzzing/extract_text_to_fp_fuzzer.py | 16 +++----- fuzzing/fuzz_helpers.py | 61 ++++++---------------------- fuzzing/page_extraction_fuzzer.py | 16 +++----- fuzzing/pdf_utils.py | 6 +-- mypy.ini | 5 ++- 6 files changed, 37 insertions(+), 83 deletions(-) diff --git a/fuzzing/extract_text_fuzzer.py b/fuzzing/extract_text_fuzzer.py index 9b270701..584b9eb5 100644 --- a/fuzzing/extract_text_fuzzer.py +++ b/fuzzing/extract_text_fuzzer.py @@ -11,10 +11,10 @@ from pdfminer.psparser import PSException -def TestOneInput(data: bytes): +def test_one_input(data: bytes) -> None: if not PDFValidator.is_valid_byte_stream(data): # Not worth continuing with this test case - return -1 + return fdp = EnhancedFuzzedDataProvider(data) @@ -28,18 +28,14 @@ def TestOneInput(data: bytes): laparams=PDFValidator.generate_layout_parameters(fdp), ) except (AssertionError, PSException): - return -1 + return except Exception as e: if PDFValidator.should_ignore_error(e): - return -1 + return raise e -def main(): +if __name__ == "__main__": prepare_pdfminer_fuzzing() - atheris.Setup(sys.argv, TestOneInput) + atheris.Setup(sys.argv, test_one_input) atheris.Fuzz() - - -if __name__ == "__main__": - main() diff --git a/fuzzing/extract_text_to_fp_fuzzer.py b/fuzzing/extract_text_to_fp_fuzzer.py index b6ee8ecd..2e8e5c4d 100644 --- a/fuzzing/extract_text_to_fp_fuzzer.py +++ b/fuzzing/extract_text_to_fp_fuzzer.py @@ -14,10 +14,10 @@ available_layout_modes = ["exact", "normal", "loose"] -def TestOneInput(data: bytes): +def test_one_input(data: bytes) -> None: if not PDFValidator.is_valid_byte_stream(data): # Not worth continuing with this test case - return -1 + return fdp = EnhancedFuzzedDataProvider(data) @@ -37,18 +37,14 @@ def TestOneInput(data: bytes): strip_control=fdp.ConsumeBool(), ) except (AssertionError, PSException): - return -1 + return except Exception as e: if PDFValidator.should_ignore_error(e): - return -1 + return raise e -def main(): - atheris.Setup(sys.argv, TestOneInput) - atheris.Fuzz() - - if __name__ == "__main__": prepare_pdfminer_fuzzing() - main() + atheris.Setup(sys.argv, test_one_input) + atheris.Fuzz() diff --git a/fuzzing/fuzz_helpers.py b/fuzzing/fuzz_helpers.py index 7c7e106f..8956f63d 100644 --- a/fuzzing/fuzz_helpers.py +++ b/fuzzing/fuzz_helpers.py @@ -1,62 +1,25 @@ import io -import tempfile -import atheris -import contextlib +from atheris import FuzzedDataProvider -class EnhancedFuzzedDataProvider(atheris.FuzzedDataProvider): + +class EnhancedFuzzedDataProvider(FuzzedDataProvider): # type: ignore[misc] def ConsumeRandomBytes(self) -> bytes: - return self.ConsumeBytes(self.ConsumeIntInRange(0, self.remaining_bytes())) + int_range = self.ConsumeIntInRange(0, self.remaining_bytes()) + return bytes(self.ConsumeBytes(int_range)) def ConsumeRandomString(self) -> str: - return self.ConsumeUnicodeNoSurrogates( - self.ConsumeIntInRange(0, self.remaining_bytes()) - ) + int_range = self.ConsumeIntInRange(0, self.remaining_bytes()) + return str(self.ConsumeUnicodeNoSurrogates(int_range)) def ConsumeRemainingString(self) -> str: - return self.ConsumeUnicodeNoSurrogates(self.remaining_bytes()) + return str(self.ConsumeUnicodeNoSurrogates(self.remaining_bytes())) def ConsumeRemainingBytes(self) -> bytes: - return self.ConsumeBytes(self.remaining_bytes()) - - @contextlib.contextmanager - def ConsumeMemoryFile( - self, all_data: bool = False, as_bytes: bool = True - ) -> io.BytesIO: - if all_data: - file_data = ( - self.ConsumeRemainingBytes() - if as_bytes - else self.ConsumeRemainingString() - ) - else: - file_data = ( - self.ConsumeRandomBytes() if as_bytes else self.ConsumeRandomString() - ) - - file = io.BytesIO(file_data) if as_bytes else io.StringIO(file_data) - yield file - file.close() + return bytes(self.ConsumeBytes(self.remaining_bytes())) - @contextlib.contextmanager - def ConsumeTemporaryFile( - self, suffix: str, all_data: bool = False, as_bytes: bool = True - ) -> str: + def ConsumeMemoryFile(self, all_data: bool = False) -> io.BytesIO: if all_data: - file_data = ( - self.ConsumeRemainingBytes() - if as_bytes - else self.ConsumeRemainingString() - ) + return io.BytesIO(self.ConsumeRemainingBytes()) else: - file_data = ( - self.ConsumeRandomBytes() if as_bytes else self.ConsumeRandomString() - ) - - mode = "w+b" if as_bytes else "w+" - tfile = tempfile.NamedTemporaryFile(mode=mode, suffix=suffix) - tfile.write(file_data) - tfile.seek(0) - tfile.flush() - yield tfile.name - tfile.close() + return io.BytesIO(self.ConsumeRandomBytes()) diff --git a/fuzzing/page_extraction_fuzzer.py b/fuzzing/page_extraction_fuzzer.py index 7794d1ee..137487d7 100755 --- a/fuzzing/page_extraction_fuzzer.py +++ b/fuzzing/page_extraction_fuzzer.py @@ -10,10 +10,10 @@ from pdfminer.psparser import PSException -def TestOneInput(data: bytes): +def test_one_input(data: bytes) -> None: if not PDFValidator.is_valid_byte_stream(data): # Not worth continuing with this test case - return -1 + return fdp = EnhancedFuzzedDataProvider(data) @@ -31,18 +31,14 @@ def TestOneInput(data: bytes): ) ) except (AssertionError, PSException): - return -1 + return except Exception as e: if PDFValidator.should_ignore_error(e): - return -1 + return raise e -def main(): +if __name__ == "__main__": prepare_pdfminer_fuzzing() - atheris.Setup(sys.argv, TestOneInput) + atheris.Setup(sys.argv, test_one_input) atheris.Fuzz() - - -if __name__ == "__main__": - main() diff --git a/fuzzing/pdf_utils.py b/fuzzing/pdf_utils.py index 4220c77b..2064e633 100644 --- a/fuzzing/pdf_utils.py +++ b/fuzzing/pdf_utils.py @@ -20,7 +20,7 @@ ] -def prepare_pdfminer_fuzzing(): +def prepare_pdfminer_fuzzing() -> None: """ Used to disable logging of the pdfminer module """ @@ -35,7 +35,7 @@ class PDFValidator: _PDF_MAGIC_BYTES = b"%PDF-" @staticmethod - @atheris.instrument_func + @atheris.instrument_func # type: ignore[misc] def is_valid_byte_stream(data: bytes) -> bool: """Quick check to see if this is worth of passing to atheris :return: Whether the byte-stream passes the basic checks @@ -48,7 +48,7 @@ def is_valid_byte_stream(data: bytes) -> bool: return True @staticmethod - @atheris.instrument_func + @atheris.instrument_func # type: ignore[misc] def generate_layout_parameters( fdp: atheris.FuzzedDataProvider, ) -> Optional[LAParams]: diff --git a/mypy.ini b/mypy.ini index 8c943f02..3d088532 100644 --- a/mypy.ini +++ b/mypy.ini @@ -30,4 +30,7 @@ ignore_missing_imports = True ignore_missing_imports = True [mypy-charset_normalizer.*] -ignore_missing_imports = True \ No newline at end of file +ignore_missing_imports = True + +[mypy-atheris.*] +ignore_missing_imports = True From a13bc787399219d74b37cf8ec6c7d1c1a140de27 Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Thu, 27 Jun 2024 19:01:12 +0200 Subject: [PATCH 14/22] Rename test_one_input to fuzz_one_input so PyCharm is not thinking they are test cases --- fuzzing/extract_text_fuzzer.py | 4 ++-- fuzzing/extract_text_to_fp_fuzzer.py | 4 ++-- fuzzing/page_extraction_fuzzer.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fuzzing/extract_text_fuzzer.py b/fuzzing/extract_text_fuzzer.py index 584b9eb5..ccee072b 100644 --- a/fuzzing/extract_text_fuzzer.py +++ b/fuzzing/extract_text_fuzzer.py @@ -11,7 +11,7 @@ from pdfminer.psparser import PSException -def test_one_input(data: bytes) -> None: +def fuzz_one_input(data: bytes) -> None: if not PDFValidator.is_valid_byte_stream(data): # Not worth continuing with this test case return @@ -37,5 +37,5 @@ def test_one_input(data: bytes) -> None: if __name__ == "__main__": prepare_pdfminer_fuzzing() - atheris.Setup(sys.argv, test_one_input) + atheris.Setup(sys.argv, fuzz_one_input) atheris.Fuzz() diff --git a/fuzzing/extract_text_to_fp_fuzzer.py b/fuzzing/extract_text_to_fp_fuzzer.py index 2e8e5c4d..b15fc334 100644 --- a/fuzzing/extract_text_to_fp_fuzzer.py +++ b/fuzzing/extract_text_to_fp_fuzzer.py @@ -14,7 +14,7 @@ available_layout_modes = ["exact", "normal", "loose"] -def test_one_input(data: bytes) -> None: +def fuzz_one_input(data: bytes) -> None: if not PDFValidator.is_valid_byte_stream(data): # Not worth continuing with this test case return @@ -46,5 +46,5 @@ def test_one_input(data: bytes) -> None: if __name__ == "__main__": prepare_pdfminer_fuzzing() - atheris.Setup(sys.argv, test_one_input) + atheris.Setup(sys.argv, fuzz_one_input) atheris.Fuzz() diff --git a/fuzzing/page_extraction_fuzzer.py b/fuzzing/page_extraction_fuzzer.py index 137487d7..e701201a 100755 --- a/fuzzing/page_extraction_fuzzer.py +++ b/fuzzing/page_extraction_fuzzer.py @@ -10,7 +10,7 @@ from pdfminer.psparser import PSException -def test_one_input(data: bytes) -> None: +def fuzz_one_input(data: bytes) -> None: if not PDFValidator.is_valid_byte_stream(data): # Not worth continuing with this test case return @@ -40,5 +40,5 @@ def test_one_input(data: bytes) -> None: if __name__ == "__main__": prepare_pdfminer_fuzzing() - atheris.Setup(sys.argv, test_one_input) + atheris.Setup(sys.argv, fuzz_one_input) atheris.Fuzz() From cd4d715520051ec10f20350cd34eccc7f9f3052f Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Thu, 27 Jun 2024 20:06:00 +0200 Subject: [PATCH 15/22] Undo fixes, so we can monitor them --- pdfminer/pdfdocument.py | 2 +- pdfminer/pdfparser.py | 4 ++-- pdfminer/utils.py | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pdfminer/pdfdocument.py b/pdfminer/pdfdocument.py index 30662d48..258e9473 100644 --- a/pdfminer/pdfdocument.py +++ b/pdfminer/pdfdocument.py @@ -977,7 +977,7 @@ def find_xref(self, parser: PDFParser) -> int: else: raise PDFNoValidXRef("Unexpected EOF") log.debug("xref found: pos=%r", prev) - assert prev is not None and prev.isdigit() + assert prev is not None return int(prev) # read xref table diff --git a/pdfminer/pdfparser.py b/pdfminer/pdfparser.py index d988da3b..992d8840 100644 --- a/pdfminer/pdfparser.py +++ b/pdfminer/pdfparser.py @@ -80,7 +80,7 @@ def do_keyword(self, pos: int, token: PSKeyword) -> None: assert self.doc is not None obj = PDFObjRef(self.doc, objid, genno) self.push((pos, obj)) - except (TypeError, PSSyntaxError): + except PSSyntaxError: pass elif token is self.KEYWORD_STREAM: # stream object @@ -163,7 +163,7 @@ def do_keyword(self, pos: int, token: PSKeyword) -> None: (objid, genno) = (int(objid), int(genno)) # type: ignore[arg-type] obj = PDFObjRef(self.doc, objid, genno) self.push((pos, obj)) - except (TypeError, PSSyntaxError): + except PSSyntaxError: pass return elif token in (self.KEYWORD_OBJ, self.KEYWORD_ENDOBJ): diff --git a/pdfminer/utils.py b/pdfminer/utils.py index 2255ce07..59cf5cd3 100644 --- a/pdfminer/utils.py +++ b/pdfminer/utils.py @@ -25,7 +25,6 @@ cast, ) - if TYPE_CHECKING: from .layout import LTComponent From 9b55c8dcf1c59b462e67727d88e5d08c46aa51cf Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Thu, 27 Jun 2024 20:31:34 +0200 Subject: [PATCH 16/22] Also fuzz None values --- fuzzing/extract_text_fuzzer.py | 14 ++++++-------- fuzzing/extract_text_to_fp_fuzzer.py | 5 ++--- fuzzing/fuzz_helpers.py | 9 +++++++++ fuzzing/page_extraction_fuzzer.py | 7 ++----- fuzzing/pdf_utils.py | 29 ++++++++++++++-------------- 5 files changed, 34 insertions(+), 30 deletions(-) diff --git a/fuzzing/extract_text_fuzzer.py b/fuzzing/extract_text_fuzzer.py index ccee072b..750ea72f 100644 --- a/fuzzing/extract_text_fuzzer.py +++ b/fuzzing/extract_text_fuzzer.py @@ -19,14 +19,12 @@ def fuzz_one_input(data: bytes) -> None: fdp = EnhancedFuzzedDataProvider(data) try: - with fdp.ConsumeMemoryFile() as f: - max_pages = fdp.ConsumeIntInRange(0, 1000) - extract_text( - f, - maxpages=max_pages, - page_numbers=fdp.ConsumeIntList(fdp.ConsumeIntInRange(0, max_pages), 2), - laparams=PDFValidator.generate_layout_parameters(fdp), - ) + extract_text( + fdp.ConsumeMemoryFile(), + maxpages=fdp.ConsumeIntInRange(0, 10), + page_numbers=fdp.ConsumeOptionalIntList(10, 0, 10), + laparams=PDFValidator.generate_layout_parameters(fdp), + ) except (AssertionError, PSException): return except Exception as e: diff --git a/fuzzing/extract_text_to_fp_fuzzer.py b/fuzzing/extract_text_to_fp_fuzzer.py index b15fc334..bfbfee63 100644 --- a/fuzzing/extract_text_to_fp_fuzzer.py +++ b/fuzzing/extract_text_to_fp_fuzzer.py @@ -23,14 +23,13 @@ def fuzz_one_input(data: bytes) -> None: try: with fdp.ConsumeMemoryFile(all_data=False) as f_in, io.BytesIO() as f_out: - max_pages = fdp.ConsumeIntInRange(0, 1000) extract_text_to_fp( f_in, f_out, output_type=fdp.PickValueInList(available_output_formats), laparams=PDFValidator.generate_layout_parameters(fdp), - maxpages=max_pages, - page_numbers=fdp.ConsumeIntList(fdp.ConsumeIntInRange(0, max_pages), 2), + maxpages=fdp.ConsumeIntInRange(0, 10), + page_numbers=fdp.ConsumeOptionalIntList(10, 0, 10), scale=fdp.ConsumeFloatInRange(0.0, 2.0), rotation=fdp.ConsumeIntInRange(0, 360), layoutmode=fdp.PickValueInList(available_layout_modes), diff --git a/fuzzing/fuzz_helpers.py b/fuzzing/fuzz_helpers.py index 8956f63d..3f627ff7 100644 --- a/fuzzing/fuzz_helpers.py +++ b/fuzzing/fuzz_helpers.py @@ -1,4 +1,5 @@ import io +from typing import List, Optional from atheris import FuzzedDataProvider @@ -23,3 +24,11 @@ def ConsumeMemoryFile(self, all_data: bool = False) -> io.BytesIO: return io.BytesIO(self.ConsumeRemainingBytes()) else: return io.BytesIO(self.ConsumeRandomBytes()) + + def ConsumeOptionalIntList( + self, max_count: int, min: int, max: int + ) -> Optional[List[int]]: + if self.ConsumeBool(): + count = self.ConsumeIntInRange(0, max_count) + return [int(i) for i in self.ConsumeIntListInRange(count, min, max)] + return None diff --git a/fuzzing/page_extraction_fuzzer.py b/fuzzing/page_extraction_fuzzer.py index e701201a..bdaafeed 100755 --- a/fuzzing/page_extraction_fuzzer.py +++ b/fuzzing/page_extraction_fuzzer.py @@ -19,14 +19,11 @@ def fuzz_one_input(data: bytes) -> None: try: with fdp.ConsumeMemoryFile() as f: - max_pages = fdp.ConsumeIntInRange(0, 1000) list( extract_pages( f, - maxpages=max_pages, - page_numbers=fdp.ConsumeIntList( - fdp.ConsumeIntInRange(0, max_pages), 2 - ), + maxpages=fdp.ConsumeIntInRange(0, 10), + page_numbers=fdp.ConsumeOptionalIntList(10, 0, 10), laparams=PDFValidator.generate_layout_parameters(fdp), ) ) diff --git a/fuzzing/pdf_utils.py b/fuzzing/pdf_utils.py index 2064e633..581ec5ab 100644 --- a/fuzzing/pdf_utils.py +++ b/fuzzing/pdf_utils.py @@ -52,20 +52,21 @@ def is_valid_byte_stream(data: bytes) -> bool: def generate_layout_parameters( fdp: atheris.FuzzedDataProvider, ) -> Optional[LAParams]: - return ( - LAParams( - line_overlap=fdp.ConsumeFloat(), - char_margin=fdp.ConsumeFloat(), - line_margin=fdp.ConsumeFloat(), - word_margin=fdp.ConsumeFloat(), - boxes_flow=fdp.ConsumeFloatInRange(-1.0, 1.0) - if fdp.ConsumeBool() - else None, - detect_vertical=fdp.ConsumeBool(), - all_texts=fdp.ConsumeBool(), - ) - if fdp.ConsumeBool() - else None + if fdp.ConsumeBool(): + return None + + boxes_flow: Optional[float] = None + if fdp.ConsumeBool(): + boxes_flow = fdp.ConsumeFloatInRange(-1.0, 1.0) + + return LAParams( + line_overlap=fdp.ConsumeFloat(), + char_margin=fdp.ConsumeFloat(), + line_margin=fdp.ConsumeFloat(), + word_margin=fdp.ConsumeFloat(), + boxes_flow=boxes_flow, + detect_vertical=fdp.ConsumeBool(), + all_texts=fdp.ConsumeBool(), ) @staticmethod From dc2d032970627b596893206bc4f477b9897bf751 Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Thu, 27 Jun 2024 20:34:18 +0200 Subject: [PATCH 17/22] Use relative imports, just like pdfminer.six package --- fuzzing/__init__.py | 0 fuzzing/extract_text_fuzzer.py | 4 ++-- fuzzing/extract_text_to_fp_fuzzer.py | 4 ++-- fuzzing/page_extraction_fuzzer.py | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 fuzzing/__init__.py diff --git a/fuzzing/__init__.py b/fuzzing/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/fuzzing/extract_text_fuzzer.py b/fuzzing/extract_text_fuzzer.py index 750ea72f..89031698 100644 --- a/fuzzing/extract_text_fuzzer.py +++ b/fuzzing/extract_text_fuzzer.py @@ -2,10 +2,10 @@ import atheris -from fuzz_helpers import EnhancedFuzzedDataProvider +from .fuzz_helpers import EnhancedFuzzedDataProvider with atheris.instrument_imports(): - from pdf_utils import PDFValidator, prepare_pdfminer_fuzzing + from .pdf_utils import PDFValidator, prepare_pdfminer_fuzzing from pdfminer.high_level import extract_text from pdfminer.psparser import PSException diff --git a/fuzzing/extract_text_to_fp_fuzzer.py b/fuzzing/extract_text_to_fp_fuzzer.py index bfbfee63..cd0780e0 100644 --- a/fuzzing/extract_text_to_fp_fuzzer.py +++ b/fuzzing/extract_text_to_fp_fuzzer.py @@ -3,10 +3,10 @@ import atheris -from fuzz_helpers import EnhancedFuzzedDataProvider +from .fuzz_helpers import EnhancedFuzzedDataProvider with atheris.instrument_imports(): - from pdf_utils import PDFValidator, prepare_pdfminer_fuzzing + from .pdf_utils import PDFValidator, prepare_pdfminer_fuzzing from pdfminer.high_level import extract_text_to_fp from pdfminer.psparser import PSException diff --git a/fuzzing/page_extraction_fuzzer.py b/fuzzing/page_extraction_fuzzer.py index bdaafeed..30db9b29 100755 --- a/fuzzing/page_extraction_fuzzer.py +++ b/fuzzing/page_extraction_fuzzer.py @@ -2,10 +2,10 @@ import atheris import sys -from fuzz_helpers import EnhancedFuzzedDataProvider +from .fuzz_helpers import EnhancedFuzzedDataProvider with atheris.instrument_imports(): - from pdf_utils import PDFValidator, prepare_pdfminer_fuzzing + from .pdf_utils import PDFValidator, prepare_pdfminer_fuzzing from pdfminer.high_level import extract_pages from pdfminer.psparser import PSException From 971f4028875ccad56ecf35a13bd90397613c9e9f Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Thu, 27 Jun 2024 20:38:32 +0200 Subject: [PATCH 18/22] Fix imports --- fuzzing/extract_text_fuzzer.py | 4 ++-- fuzzing/extract_text_to_fp_fuzzer.py | 2 +- fuzzing/page_extraction_fuzzer.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fuzzing/extract_text_fuzzer.py b/fuzzing/extract_text_fuzzer.py index 89031698..1a0083c4 100644 --- a/fuzzing/extract_text_fuzzer.py +++ b/fuzzing/extract_text_fuzzer.py @@ -2,10 +2,10 @@ import atheris -from .fuzz_helpers import EnhancedFuzzedDataProvider +from fuzzing.fuzz_helpers import EnhancedFuzzedDataProvider with atheris.instrument_imports(): - from .pdf_utils import PDFValidator, prepare_pdfminer_fuzzing + from fuzzing.pdf_utils import PDFValidator, prepare_pdfminer_fuzzing from pdfminer.high_level import extract_text from pdfminer.psparser import PSException diff --git a/fuzzing/extract_text_to_fp_fuzzer.py b/fuzzing/extract_text_to_fp_fuzzer.py index cd0780e0..f6b6a77a 100644 --- a/fuzzing/extract_text_to_fp_fuzzer.py +++ b/fuzzing/extract_text_to_fp_fuzzer.py @@ -3,7 +3,7 @@ import atheris -from .fuzz_helpers import EnhancedFuzzedDataProvider +from fuzzing.fuzz_helpers import EnhancedFuzzedDataProvider with atheris.instrument_imports(): from .pdf_utils import PDFValidator, prepare_pdfminer_fuzzing diff --git a/fuzzing/page_extraction_fuzzer.py b/fuzzing/page_extraction_fuzzer.py index 30db9b29..b25cf2f1 100755 --- a/fuzzing/page_extraction_fuzzer.py +++ b/fuzzing/page_extraction_fuzzer.py @@ -2,7 +2,7 @@ import atheris import sys -from .fuzz_helpers import EnhancedFuzzedDataProvider +from fuzzing.fuzz_helpers import EnhancedFuzzedDataProvider with atheris.instrument_imports(): from .pdf_utils import PDFValidator, prepare_pdfminer_fuzzing From 067f94faac8ea8393c7da00efeff3b01e050f5bd Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Thu, 27 Jun 2024 20:43:02 +0200 Subject: [PATCH 19/22] Simplify pdf_utils.py by removing class, just functions --- fuzzing/extract_text_fuzzer.py | 17 ++-- fuzzing/extract_text_to_fp_fuzzer.py | 17 ++-- ...uzz_helpers.py => fuzzed_data_provider.py} | 2 +- fuzzing/page_extraction_fuzzer.py | 17 ++-- fuzzing/pdf_utils.py | 81 ------------------- fuzzing/utils.py | 75 +++++++++++++++++ 6 files changed, 109 insertions(+), 100 deletions(-) rename fuzzing/{fuzz_helpers.py => fuzzed_data_provider.py} (94%) delete mode 100644 fuzzing/pdf_utils.py create mode 100644 fuzzing/utils.py diff --git a/fuzzing/extract_text_fuzzer.py b/fuzzing/extract_text_fuzzer.py index 1a0083c4..53ee70f3 100644 --- a/fuzzing/extract_text_fuzzer.py +++ b/fuzzing/extract_text_fuzzer.py @@ -2,33 +2,38 @@ import atheris -from fuzzing.fuzz_helpers import EnhancedFuzzedDataProvider +from fuzzing.fuzzed_data_provider import PdfminerFuzzedDataProvider with atheris.instrument_imports(): - from fuzzing.pdf_utils import PDFValidator, prepare_pdfminer_fuzzing + from fuzzing.utils import ( + prepare_pdfminer_fuzzing, + is_valid_byte_stream, + generate_layout_parameters, + should_ignore_error, + ) from pdfminer.high_level import extract_text from pdfminer.psparser import PSException def fuzz_one_input(data: bytes) -> None: - if not PDFValidator.is_valid_byte_stream(data): + if not is_valid_byte_stream(data): # Not worth continuing with this test case return - fdp = EnhancedFuzzedDataProvider(data) + fdp = PdfminerFuzzedDataProvider(data) try: extract_text( fdp.ConsumeMemoryFile(), maxpages=fdp.ConsumeIntInRange(0, 10), page_numbers=fdp.ConsumeOptionalIntList(10, 0, 10), - laparams=PDFValidator.generate_layout_parameters(fdp), + laparams=generate_layout_parameters(fdp), ) except (AssertionError, PSException): return except Exception as e: - if PDFValidator.should_ignore_error(e): + if should_ignore_error(e): return raise e diff --git a/fuzzing/extract_text_to_fp_fuzzer.py b/fuzzing/extract_text_to_fp_fuzzer.py index f6b6a77a..0014ef77 100644 --- a/fuzzing/extract_text_to_fp_fuzzer.py +++ b/fuzzing/extract_text_to_fp_fuzzer.py @@ -3,10 +3,15 @@ import atheris -from fuzzing.fuzz_helpers import EnhancedFuzzedDataProvider +from fuzzing.fuzzed_data_provider import PdfminerFuzzedDataProvider with atheris.instrument_imports(): - from .pdf_utils import PDFValidator, prepare_pdfminer_fuzzing + from fuzzing.utils import ( + prepare_pdfminer_fuzzing, + is_valid_byte_stream, + generate_layout_parameters, + should_ignore_error, + ) from pdfminer.high_level import extract_text_to_fp from pdfminer.psparser import PSException @@ -15,11 +20,11 @@ def fuzz_one_input(data: bytes) -> None: - if not PDFValidator.is_valid_byte_stream(data): + if not is_valid_byte_stream(data): # Not worth continuing with this test case return - fdp = EnhancedFuzzedDataProvider(data) + fdp = PdfminerFuzzedDataProvider(data) try: with fdp.ConsumeMemoryFile(all_data=False) as f_in, io.BytesIO() as f_out: @@ -27,7 +32,7 @@ def fuzz_one_input(data: bytes) -> None: f_in, f_out, output_type=fdp.PickValueInList(available_output_formats), - laparams=PDFValidator.generate_layout_parameters(fdp), + laparams=generate_layout_parameters(fdp), maxpages=fdp.ConsumeIntInRange(0, 10), page_numbers=fdp.ConsumeOptionalIntList(10, 0, 10), scale=fdp.ConsumeFloatInRange(0.0, 2.0), @@ -38,7 +43,7 @@ def fuzz_one_input(data: bytes) -> None: except (AssertionError, PSException): return except Exception as e: - if PDFValidator.should_ignore_error(e): + if should_ignore_error(e): return raise e diff --git a/fuzzing/fuzz_helpers.py b/fuzzing/fuzzed_data_provider.py similarity index 94% rename from fuzzing/fuzz_helpers.py rename to fuzzing/fuzzed_data_provider.py index 3f627ff7..1992fbab 100644 --- a/fuzzing/fuzz_helpers.py +++ b/fuzzing/fuzzed_data_provider.py @@ -4,7 +4,7 @@ from atheris import FuzzedDataProvider -class EnhancedFuzzedDataProvider(FuzzedDataProvider): # type: ignore[misc] +class PdfminerFuzzedDataProvider(FuzzedDataProvider): # type: ignore[misc] def ConsumeRandomBytes(self) -> bytes: int_range = self.ConsumeIntInRange(0, self.remaining_bytes()) return bytes(self.ConsumeBytes(int_range)) diff --git a/fuzzing/page_extraction_fuzzer.py b/fuzzing/page_extraction_fuzzer.py index b25cf2f1..6db915ad 100755 --- a/fuzzing/page_extraction_fuzzer.py +++ b/fuzzing/page_extraction_fuzzer.py @@ -2,20 +2,25 @@ import atheris import sys -from fuzzing.fuzz_helpers import EnhancedFuzzedDataProvider +from fuzzing.fuzzed_data_provider import PdfminerFuzzedDataProvider with atheris.instrument_imports(): - from .pdf_utils import PDFValidator, prepare_pdfminer_fuzzing + from fuzzing.utils import ( + prepare_pdfminer_fuzzing, + is_valid_byte_stream, + generate_layout_parameters, + should_ignore_error, + ) from pdfminer.high_level import extract_pages from pdfminer.psparser import PSException def fuzz_one_input(data: bytes) -> None: - if not PDFValidator.is_valid_byte_stream(data): + if not is_valid_byte_stream(data): # Not worth continuing with this test case return - fdp = EnhancedFuzzedDataProvider(data) + fdp = PdfminerFuzzedDataProvider(data) try: with fdp.ConsumeMemoryFile() as f: @@ -24,13 +29,13 @@ def fuzz_one_input(data: bytes) -> None: f, maxpages=fdp.ConsumeIntInRange(0, 10), page_numbers=fdp.ConsumeOptionalIntList(10, 0, 10), - laparams=PDFValidator.generate_layout_parameters(fdp), + laparams=generate_layout_parameters(fdp), ) ) except (AssertionError, PSException): return except Exception as e: - if PDFValidator.should_ignore_error(e): + if should_ignore_error(e): return raise e diff --git a/fuzzing/pdf_utils.py b/fuzzing/pdf_utils.py deleted file mode 100644 index 581ec5ab..00000000 --- a/fuzzing/pdf_utils.py +++ /dev/null @@ -1,81 +0,0 @@ -""" -Utilities shared across the various PDF fuzzing harnesses -""" -import logging -from typing import Optional - -import atheris - -from pdfminer.layout import LAParams -from pdfminer.psparser import PSException - -# List of all exception message substrings explicitly raised by pdfminer that do not -# inherit from PSException -_EXPLICIT_EXCEPTION_MESSAGES = [ - "Unsupported", - "duplicate labels", - "AcroForm", - "SASLPrep", - "Invalid", -] - - -def prepare_pdfminer_fuzzing() -> None: - """ - Used to disable logging of the pdfminer module - """ - logging.getLogger("pdfminer").setLevel(logging.CRITICAL) - - -class PDFValidator: - """ - Custom mutator class for PDFs for more efficient fuzzing - """ - - _PDF_MAGIC_BYTES = b"%PDF-" - - @staticmethod - @atheris.instrument_func # type: ignore[misc] - def is_valid_byte_stream(data: bytes) -> bool: - """Quick check to see if this is worth of passing to atheris - :return: Whether the byte-stream passes the basic checks - """ - if not data.startswith(PDFValidator._PDF_MAGIC_BYTES): - return False - if b"/Root" not in data: - return False - - return True - - @staticmethod - @atheris.instrument_func # type: ignore[misc] - def generate_layout_parameters( - fdp: atheris.FuzzedDataProvider, - ) -> Optional[LAParams]: - if fdp.ConsumeBool(): - return None - - boxes_flow: Optional[float] = None - if fdp.ConsumeBool(): - boxes_flow = fdp.ConsumeFloatInRange(-1.0, 1.0) - - return LAParams( - line_overlap=fdp.ConsumeFloat(), - char_margin=fdp.ConsumeFloat(), - line_margin=fdp.ConsumeFloat(), - word_margin=fdp.ConsumeFloat(), - boxes_flow=boxes_flow, - detect_vertical=fdp.ConsumeBool(), - all_texts=fdp.ConsumeBool(), - ) - - @staticmethod - def should_ignore_error(e: Exception) -> bool: - """ - Determines if the given raised exception is explicitly raised by pdfminer - :param e: The exception to check - :return: Whether the exception should be ignored or re-thrown - """ - return isinstance(e, PSException) or any( - em_ss in str(e) for em_ss in _EXPLICIT_EXCEPTION_MESSAGES - ) diff --git a/fuzzing/utils.py b/fuzzing/utils.py new file mode 100644 index 00000000..e869a5a3 --- /dev/null +++ b/fuzzing/utils.py @@ -0,0 +1,75 @@ +""" +Utilities shared across the various PDF fuzzing harnesses +""" +import logging +from typing import Optional + +import atheris + +from pdfminer.layout import LAParams +from pdfminer.psparser import PSException + +PDF_MAGIC_BYTES = b"%PDF-" + +# List of all exception message substrings explicitly raised by pdfminer that do not +# inherit from PSException +_EXPLICIT_EXCEPTION_MESSAGES = [ + "Unsupported", + "duplicate labels", + "AcroForm", + "SASLPrep", + "Invalid", +] + + +def prepare_pdfminer_fuzzing() -> None: + """ + Used to disable logging of the pdfminer module + """ + logging.getLogger("pdfminer").setLevel(logging.CRITICAL) + + +def should_ignore_error(e: Exception) -> bool: + """ + Determines if the given raised exception is explicitly raised by pdfminer + :param e: The exception to check + :return: Whether the exception should be ignored or re-thrown + """ + return isinstance(e, PSException) or any( + em_ss in str(e) for em_ss in _EXPLICIT_EXCEPTION_MESSAGES + ) + + +@atheris.instrument_func # type: ignore[misc] +def generate_layout_parameters( + fdp: atheris.FuzzedDataProvider, +) -> Optional[LAParams]: + if fdp.ConsumeBool(): + return None + + boxes_flow: Optional[float] = None + if fdp.ConsumeBool(): + boxes_flow = fdp.ConsumeFloatInRange(-1.0, 1.0) + + return LAParams( + line_overlap=fdp.ConsumeFloat(), + char_margin=fdp.ConsumeFloat(), + line_margin=fdp.ConsumeFloat(), + word_margin=fdp.ConsumeFloat(), + boxes_flow=boxes_flow, + detect_vertical=fdp.ConsumeBool(), + all_texts=fdp.ConsumeBool(), + ) + + +@atheris.instrument_func # type: ignore[misc] +def is_valid_byte_stream(data: bytes) -> bool: + """Quick check to see if this is worth of passing to atheris + :return: Whether the byte-stream passes the basic checks + """ + if not data.startswith(PDF_MAGIC_BYTES): + return False + if b"/Root" not in data: + return False + + return True From 2c371db264a4f50a1ea9ac7986c793096cb0368e Mon Sep 17 00:00:00 2001 From: Pieter Marsman Date: Thu, 27 Jun 2024 22:04:58 +0200 Subject: [PATCH 20/22] Subclassing all internal exceptions to PSException such that a single except can catch all --- fuzzing/extract_text_fuzzer.py | 7 +----- fuzzing/extract_text_to_fp_fuzzer.py | 7 +----- fuzzing/page_extraction_fuzzer.py | 7 +----- fuzzing/utils.py | 22 ------------------- pdfminer/_saslprep.py | 6 +++-- pdfminer/ccitt.py | 13 +++++++---- pdfminer/cmapdb.py | 8 +++---- pdfminer/converter.py | 7 +++--- pdfminer/encodingdb.py | 7 +++--- pdfminer/high_level.py | 3 ++- pdfminer/image.py | 5 +++-- pdfminer/jbig2.py | 6 +++-- pdfminer/layout.py | 13 ++++++----- pdfminer/lzw.py | 6 +++-- pdfminer/pdfdocument.py | 22 ++++++++----------- pdfminer/pdfexceptions.py | 33 ++++++++++++++++++++++++++++ pdfminer/pdffont.py | 12 +++++----- pdfminer/pdfinterp.py | 6 ++--- pdfminer/pdfpage.py | 2 +- pdfminer/pdfparser.py | 5 ++--- pdfminer/pdftypes.py | 30 +++++++------------------ pdfminer/psexceptions.py | 18 +++++++++++++++ pdfminer/psparser.py | 28 +++++++---------------- pdfminer/utils.py | 10 +++++---- tests/test_pdfdocument.py | 3 ++- tests/test_pdfminer_psparser.py | 3 ++- tools/dumppdf.py | 18 +++++++++++---- tools/pdf2txt.py | 3 ++- 28 files changed, 162 insertions(+), 148 deletions(-) create mode 100644 pdfminer/pdfexceptions.py create mode 100644 pdfminer/psexceptions.py diff --git a/fuzzing/extract_text_fuzzer.py b/fuzzing/extract_text_fuzzer.py index 53ee70f3..219badb5 100644 --- a/fuzzing/extract_text_fuzzer.py +++ b/fuzzing/extract_text_fuzzer.py @@ -9,11 +9,10 @@ prepare_pdfminer_fuzzing, is_valid_byte_stream, generate_layout_parameters, - should_ignore_error, ) from pdfminer.high_level import extract_text -from pdfminer.psparser import PSException +from pdfminer.psexceptions import PSException def fuzz_one_input(data: bytes) -> None: @@ -32,10 +31,6 @@ def fuzz_one_input(data: bytes) -> None: ) except (AssertionError, PSException): return - except Exception as e: - if should_ignore_error(e): - return - raise e if __name__ == "__main__": diff --git a/fuzzing/extract_text_to_fp_fuzzer.py b/fuzzing/extract_text_to_fp_fuzzer.py index 0014ef77..302062d9 100644 --- a/fuzzing/extract_text_to_fp_fuzzer.py +++ b/fuzzing/extract_text_to_fp_fuzzer.py @@ -10,10 +10,9 @@ prepare_pdfminer_fuzzing, is_valid_byte_stream, generate_layout_parameters, - should_ignore_error, ) from pdfminer.high_level import extract_text_to_fp - from pdfminer.psparser import PSException + from pdfminer.psexceptions import PSException available_output_formats = ["text", "html", "xml", "tag"] available_layout_modes = ["exact", "normal", "loose"] @@ -42,10 +41,6 @@ def fuzz_one_input(data: bytes) -> None: ) except (AssertionError, PSException): return - except Exception as e: - if should_ignore_error(e): - return - raise e if __name__ == "__main__": diff --git a/fuzzing/page_extraction_fuzzer.py b/fuzzing/page_extraction_fuzzer.py index 6db915ad..435cdb69 100755 --- a/fuzzing/page_extraction_fuzzer.py +++ b/fuzzing/page_extraction_fuzzer.py @@ -9,10 +9,9 @@ prepare_pdfminer_fuzzing, is_valid_byte_stream, generate_layout_parameters, - should_ignore_error, ) from pdfminer.high_level import extract_pages - from pdfminer.psparser import PSException + from pdfminer.psexceptions import PSException def fuzz_one_input(data: bytes) -> None: @@ -34,10 +33,6 @@ def fuzz_one_input(data: bytes) -> None: ) except (AssertionError, PSException): return - except Exception as e: - if should_ignore_error(e): - return - raise e if __name__ == "__main__": diff --git a/fuzzing/utils.py b/fuzzing/utils.py index e869a5a3..6c8e5a0f 100644 --- a/fuzzing/utils.py +++ b/fuzzing/utils.py @@ -7,20 +7,9 @@ import atheris from pdfminer.layout import LAParams -from pdfminer.psparser import PSException PDF_MAGIC_BYTES = b"%PDF-" -# List of all exception message substrings explicitly raised by pdfminer that do not -# inherit from PSException -_EXPLICIT_EXCEPTION_MESSAGES = [ - "Unsupported", - "duplicate labels", - "AcroForm", - "SASLPrep", - "Invalid", -] - def prepare_pdfminer_fuzzing() -> None: """ @@ -29,17 +18,6 @@ def prepare_pdfminer_fuzzing() -> None: logging.getLogger("pdfminer").setLevel(logging.CRITICAL) -def should_ignore_error(e: Exception) -> bool: - """ - Determines if the given raised exception is explicitly raised by pdfminer - :param e: The exception to check - :return: Whether the exception should be ignored or re-thrown - """ - return isinstance(e, PSException) or any( - em_ss in str(e) for em_ss in _EXPLICIT_EXCEPTION_MESSAGES - ) - - @atheris.instrument_func # type: ignore[misc] def generate_layout_parameters( fdp: atheris.FuzzedDataProvider, diff --git a/pdfminer/_saslprep.py b/pdfminer/_saslprep.py index 1f243181..d56ca16b 100644 --- a/pdfminer/_saslprep.py +++ b/pdfminer/_saslprep.py @@ -24,6 +24,8 @@ from typing import Callable, Tuple import unicodedata +from .pdfexceptions import PDFValueError + # RFC4013 section 2.3 prohibited output. _PROHIBITED: Tuple[Callable[[str], bool], ...] = ( # A strict reading of RFC 4013 requires table c12 here, but @@ -77,7 +79,7 @@ def saslprep(data: str, prohibit_unassigned_code_points: bool = True) -> str: # RFC3454, Section 6, #3. If a string contains any # RandALCat character, the first and last characters # MUST be RandALCat characters. - raise ValueError("SASLprep: failed bidirectional check") + raise PDFValueError("SASLprep: failed bidirectional check") # RFC3454, Section 6, #2. If a string contains any RandALCat # character, it MUST NOT contain any LCat character. prohibited = prohibited + (stringprep.in_table_d2,) @@ -90,6 +92,6 @@ def saslprep(data: str, prohibit_unassigned_code_points: bool = True) -> str: # RFC3454 section 2, step 3 and 4 - Prohibit and check bidi for char in data: if any(in_table(char) for in_table in prohibited): - raise ValueError("SASLprep: failed prohibited character check") + raise PDFValueError("SASLprep: failed prohibited character check") return data diff --git a/pdfminer/ccitt.py b/pdfminer/ccitt.py index e64bf492..b51ef2bb 100644 --- a/pdfminer/ccitt.py +++ b/pdfminer/ccitt.py @@ -25,6 +25,8 @@ cast, ) +from .pdfexceptions import PDFException, PDFValueError + def get_bytes(data: bytes) -> Iterator[int]: yield from data @@ -331,13 +333,16 @@ class CCITTG4Parser(BitParser): BitParser.add(UNCOMPRESSED, "T00000", "00000000011") BitParser.add(UNCOMPRESSED, "T10000", "00000000010") - class EOFB(Exception): + class CCITTException(PDFException): + pass + + class EOFB(CCITTException): pass - class InvalidData(Exception): + class InvalidData(CCITTException): pass - class ByteSkip(Exception): + class ByteSkip(CCITTException): pass _color: int @@ -584,7 +589,7 @@ def ccittfaxdecode(data: bytes, params: Dict[str, object]) -> bytes: reversed = cast(bool, params.get("BlackIs1")) parser = CCITTFaxDecoder(cols, bytealign=bytealign, reversed=reversed) else: - raise ValueError(K) + raise PDFValueError(K) parser.feedbytes(data) return parser.close() diff --git a/pdfminer/cmapdb.py b/pdfminer/cmapdb.py index f0c43ab7..df11c01c 100644 --- a/pdfminer/cmapdb.py +++ b/pdfminer/cmapdb.py @@ -32,13 +32,13 @@ Set, ) +from pdfminer.pdfexceptions import PDFException, PDFTypeError from .encodingdb import name2unicode from .psparser import KWD -from .psparser import PSEOF +from pdfminer.psexceptions import PSEOF, PSSyntaxError from .psparser import PSKeyword from .psparser import PSLiteral from .psparser import PSStackParser -from .psparser import PSSyntaxError from .psparser import literal_name from .utils import choplist from .utils import nunpack @@ -46,7 +46,7 @@ log = logging.getLogger(__name__) -class CMapError(Exception): +class CMapError(PDFException): pass @@ -202,7 +202,7 @@ def add_cid2unichr(self, cid: int, code: Union[PSLiteral, bytes, int]) -> None: elif isinstance(code, int): unichr = chr(code) else: - raise TypeError(code) + raise PDFTypeError(code) # A0 = non-breaking space, some weird fonts can have a collision on a cid here. if unichr == "\u00A0" and self.cid2unichr.get(cid) == " ": diff --git a/pdfminer/converter.py b/pdfminer/converter.py index 9cc2ac5f..3a390d49 100644 --- a/pdfminer/converter.py +++ b/pdfminer/converter.py @@ -41,6 +41,7 @@ from .pdfinterp import PDFGraphicState, PDFResourceManager from .pdfpage import PDFPage from .pdftypes import PDFStream +from .pdfexceptions import PDFValueError from .utils import AnyIO, Point, Matrix, Rect, PathSegment, make_compat_str from .utils import apply_matrix_pt from .utils import bbox2str @@ -410,9 +411,9 @@ def __init__( # write() assumes a codec for binary I/O, or no codec for text I/O. if self.outfp_binary and not self.codec: - raise ValueError("Codec is required for a binary I/O output") + raise PDFValueError("Codec is required for a binary I/O output") if not self.outfp_binary and self.codec: - raise ValueError("Codec must not be specified for a text I/O output") + raise PDFValueError("Codec must not be specified for a text I/O output") if text_colors is None: text_colors = {"char": "black"} @@ -700,7 +701,7 @@ def __init__( # write() assumes a codec for binary I/O, or no codec for text I/O. if self.outfp_binary == (not self.codec): - raise ValueError("Codec is required for a binary I/O output") + raise PDFValueError("Codec is required for a binary I/O output") self.imagewriter = imagewriter self.stripcontrol = stripcontrol diff --git a/pdfminer/encodingdb.py b/pdfminer/encodingdb.py index c7edac5c..2a08935e 100644 --- a/pdfminer/encodingdb.py +++ b/pdfminer/encodingdb.py @@ -2,6 +2,7 @@ import re from typing import Dict, Iterable, Optional, cast +from .pdfexceptions import PDFKeyError from .glyphlist import glyphname2unicode from .latin_enc import ENCODING from .psparser import PSLiteral @@ -26,7 +27,7 @@ def name2unicode(name: str) -> str: otherwise a KeyError """ if not isinstance(name, str): - raise KeyError( + raise PDFKeyError( 'Could not convert unicode name "%s" to character because ' "it should be of type str but is of type %s" % (name, type(name)) ) @@ -62,7 +63,7 @@ def name2unicode(name: str) -> str: raise_key_error_for_invalid_unicode(unicode_digit) return chr(unicode_digit) - raise KeyError( + raise PDFKeyError( 'Could not convert unicode name "%s" to character because ' "it does not match specification" % name ) @@ -75,7 +76,7 @@ def raise_key_error_for_invalid_unicode(unicode_digit: int) -> None: :raises KeyError if unicode digit is invalid """ if 55295 < unicode_digit < 57344: - raise KeyError( + raise PDFKeyError( "Unicode digit %d is invalid because " "it is in the range D800 through DFFF" % unicode_digit ) diff --git a/pdfminer/high_level.py b/pdfminer/high_level.py index 6587fdee..93ec2ed1 100644 --- a/pdfminer/high_level.py +++ b/pdfminer/high_level.py @@ -5,6 +5,7 @@ from io import StringIO from typing import Any, BinaryIO, Container, Iterator, Optional, cast +from .pdfexceptions import PDFValueError from .converter import ( XMLConverter, HTMLConverter, @@ -117,7 +118,7 @@ def extract_text_to_fp( else: msg = f"Output type can be text, html, xml or tag but is " f"{output_type}" - raise ValueError(msg) + raise PDFValueError(msg) assert device is not None interpreter = PDFPageInterpreter(rsrcmgr, device) diff --git a/pdfminer/image.py b/pdfminer/image.py index 5d6ab5a0..52aec4bb 100644 --- a/pdfminer/image.py +++ b/pdfminer/image.py @@ -21,6 +21,7 @@ LITERALS_JPX_DECODE, LITERALS_FLATE_DECODE, ) +from .pdfexceptions import PDFValueError PIL_ERROR_MESSAGE = ( "Could not import Pillow. This dependency of pdfminer.six is not " @@ -46,7 +47,7 @@ def __init__(self, fp: BinaryIO, bits: int, width: int, height: int) -> None: elif bits == 24: ncols = 0 else: - raise ValueError(bits) + raise PDFValueError(bits) self.linesize = align32((self.width * self.bits + 7) // 8) self.datasize = self.linesize * self.height headersize = 14 + 40 + ncols * 4 @@ -189,7 +190,7 @@ def _save_jbig2(self, image: LTImage) -> str: "There should never be more than one JBIG2Globals " "associated with a JBIG2 embedded image" ) - raise ValueError(msg) + raise PDFValueError(msg) if len(global_streams) == 1: input_stream.write(global_streams[0].get_data().rstrip(b"\n")) input_stream.write(image.stream.get_data()) diff --git a/pdfminer/jbig2.py b/pdfminer/jbig2.py index 113ca80c..f1e4f7ac 100644 --- a/pdfminer/jbig2.py +++ b/pdfminer/jbig2.py @@ -3,6 +3,8 @@ from struct import pack, unpack, calcsize from typing import BinaryIO, Dict, Iterable, List, Optional, Tuple, Union, cast +from .pdfexceptions import PDFValueError + # segment structure base SEG_STRUCT = [ (">L", "number"), @@ -47,7 +49,7 @@ def masked_value(mask: int, value: int) -> int: if bit_set(bit_pos, mask): return (value & mask) >> bit_pos - raise Exception("Invalid mask or value") + raise PDFValueError("Invalid mask or value") def mask_value(mask: int, value: int) -> int: @@ -55,7 +57,7 @@ def mask_value(mask: int, value: int) -> int: if bit_set(bit_pos, mask): return (value & (mask >> bit_pos)) << bit_pos - raise Exception("Invalid mask or value") + raise PDFValueError("Invalid mask or value") def unpack_int(format: str, buffer: bytes) -> int: diff --git a/pdfminer/layout.py b/pdfminer/layout.py index 408a527a..ebaac1e2 100644 --- a/pdfminer/layout.py +++ b/pdfminer/layout.py @@ -20,6 +20,7 @@ from .pdfinterp import Color from .pdfinterp import PDFGraphicState from .pdftypes import PDFStream +from .pdfexceptions import PDFTypeError, PDFValueError from .utils import INF, PathSegment from .utils import LTComponentT from .utils import Matrix @@ -105,9 +106,9 @@ def _validate(self) -> None: if not ( isinstance(self.boxes_flow, int) or isinstance(self.boxes_flow, float) ): - raise TypeError(boxes_flow_err_msg) + raise PDFTypeError(boxes_flow_err_msg) if not -1 <= self.boxes_flow <= 1: - raise ValueError(boxes_flow_err_msg) + raise PDFValueError(boxes_flow_err_msg) def __repr__(self) -> str: return ( @@ -148,16 +149,16 @@ def __repr__(self) -> str: # Disable comparison. def __lt__(self, _: object) -> bool: - raise ValueError + raise PDFValueError def __le__(self, _: object) -> bool: - raise ValueError + raise PDFValueError def __gt__(self, _: object) -> bool: - raise ValueError + raise PDFValueError def __ge__(self, _: object) -> bool: - raise ValueError + raise PDFValueError def set_bbox(self, bbox: Rect) -> None: (x0, y0, x1, y1) = bbox diff --git a/pdfminer/lzw.py b/pdfminer/lzw.py index 47dd3dc1..30e303fc 100644 --- a/pdfminer/lzw.py +++ b/pdfminer/lzw.py @@ -2,10 +2,12 @@ from io import BytesIO from typing import BinaryIO, Iterator, List, Optional, cast +from .pdfexceptions import PDFException, PDFEOFError + logger = logging.getLogger(__name__) -class CorruptDataError(Exception): +class CorruptDataError(PDFException): pass @@ -39,7 +41,7 @@ def readbits(self, bits: int) -> int: bits -= r x = self.fp.read(1) if not x: - raise EOFError + raise PDFEOFError self.buff = ord(x) self.bpos = 0 return v diff --git a/pdfminer/pdfdocument.py b/pdfminer/pdfdocument.py index 258e9473..e9f91ad9 100644 --- a/pdfminer/pdfdocument.py +++ b/pdfminer/pdfdocument.py @@ -28,10 +28,7 @@ from .pdfparser import PDFSyntaxError, PDFParser, PDFStreamParser from .pdftypes import ( DecipherCallable, - PDFException, - PDFTypeError, PDFStream, - PDFObjectNotFound, decipher_all, int_value, str_value, @@ -40,7 +37,9 @@ dict_value, stream_value, ) -from .psparser import PSEOF, literal_name, LIT, KWD +from .pdfexceptions import PDFException, PDFTypeError, PDFObjectNotFound, PDFKeyError +from .psparser import literal_name, LIT, KWD +from .psexceptions import PSEOF from .utils import choplist, decode_text, nunpack, format_int_roman, format_int_alpha log = logging.getLogger(__name__) @@ -130,7 +129,7 @@ def get_objids(self) -> Iterable[int]: # (strmid, index, genno) # or (None, pos, genno) def get_pos(self, objid: int) -> Tuple[Optional[int], int, int]: - raise KeyError(objid) + raise PDFKeyError(objid) def load(self, parser: PDFParser) -> None: raise NotImplementedError @@ -204,10 +203,7 @@ def get_objids(self) -> KeysView[int]: return self.offsets.keys() def get_pos(self, objid: int) -> Tuple[Optional[int], int, int]: - try: - return self.offsets[objid] - except KeyError: - raise + return self.offsets[objid] class PDFXRefFallback(PDFXRef): @@ -323,7 +319,7 @@ def get_pos(self, objid: int) -> Tuple[Optional[int], int, int]: else: index += nobjs else: - raise KeyError(objid) + raise PDFKeyError(objid) assert self.entlen is not None assert self.data is not None assert self.fl1 is not None and self.fl2 is not None and self.fl3 is not None @@ -338,7 +334,7 @@ def get_pos(self, objid: int) -> Tuple[Optional[int], int, int]: return (f2, f3, 0) else: # this is a free object - raise KeyError(objid) + raise PDFKeyError(objid) class PDFStandardSecurityHandler: @@ -924,7 +920,7 @@ def lookup_name(self, cat: str, key: Union[str, bytes]) -> Any: try: names = dict_value(self.catalog["Names"]) except (PDFTypeError, KeyError): - raise KeyError((cat, key)) + raise PDFKeyError((cat, key)) # may raise KeyError d0 = dict_value(names[cat]) @@ -944,7 +940,7 @@ def lookup(d: Dict[str, Any]) -> Any: v = lookup(dict_value(c)) if v: return v - raise KeyError((cat, key)) + raise PDFKeyError((cat, key)) return lookup(d0) diff --git a/pdfminer/pdfexceptions.py b/pdfminer/pdfexceptions.py new file mode 100644 index 00000000..224c28fe --- /dev/null +++ b/pdfminer/pdfexceptions.py @@ -0,0 +1,33 @@ +from pdfminer.psexceptions import PSException + + +class PDFException(PSException): + pass + + +class PDFTypeError(PDFException, TypeError): + pass + + +class PDFValueError(PDFException, ValueError): + pass + + +class PDFObjectNotFound(PDFException): + pass + + +class PDFNotImplementedError(PDFException, NotImplementedError): + pass + + +class PDFKeyError(PDFException, KeyError): + pass + + +class PDFEOFError(PDFException, EOFError): + pass + + +class PDFIOError(PDFException, IOError): + pass diff --git a/pdfminer/pdffont.py b/pdfminer/pdffont.py index 248c8c6b..b521cd52 100644 --- a/pdfminer/pdffont.py +++ b/pdfminer/pdffont.py @@ -28,8 +28,8 @@ from .encodingdb import EncodingDB from .encodingdb import name2unicode from .fontmetrics import FONT_METRICS -from .pdftypes import PDFException from .pdftypes import PDFStream +from pdfminer.pdfexceptions import PDFException, PDFValueError, PDFKeyError from .pdftypes import dict_value from .pdftypes import int_value from .pdftypes import list_value @@ -37,8 +37,8 @@ from .pdftypes import resolve1, resolve_all from .pdftypes import stream_value from .psparser import KWD +from pdfminer.psexceptions import PSEOF from .psparser import LIT -from .psparser import PSEOF from .psparser import PSKeyword from .psparser import PSLiteral from .psparser import PSStackParser @@ -674,7 +674,7 @@ def __init__(self, name: str, fp: BinaryIO) -> None: self.gid2code[gid] = code code += 1 else: - raise ValueError("unsupported encoding format: %r" % format) + raise PDFValueError("unsupported encoding format: %r" % format) # Charsets self.name2gid = {} self.gid2name = {} @@ -705,7 +705,7 @@ def __init__(self, name: str, fp: BinaryIO) -> None: # Format 2 assert False, str(("Unhandled", format)) else: - raise ValueError("unsupported charset format: %r" % format) + raise PDFValueError("unsupported charset format: %r" % format) return def getstr(self, sid: int) -> Union[str, bytes]: @@ -717,7 +717,7 @@ def getstr(self, sid: int) -> Union[str, bytes]: class TrueTypeFont: - class CMapNotFound(Exception): + class CMapNotFound(PDFException): pass def __init__(self, name: str, fp: BinaryIO) -> None: @@ -1187,7 +1187,7 @@ def char_disp(self, cid: int) -> Union[float, Tuple[Optional[float], float]]: def to_unichr(self, cid: int) -> str: try: if not self.unicode_map: - raise KeyError(cid) + raise PDFKeyError(cid) return self.unicode_map.get_unichr(cid) except KeyError: raise PDFUnicodeNotDefined(self.cidcoding, cid) diff --git a/pdfminer/pdfinterp.py b/pdfminer/pdfinterp.py index 0ac8e5ad..79b351a6 100644 --- a/pdfminer/pdfinterp.py +++ b/pdfminer/pdfinterp.py @@ -18,18 +18,18 @@ from .pdffont import PDFType1Font from .pdffont import PDFType3Font from .pdfpage import PDFPage -from .pdftypes import PDFException from .pdftypes import PDFObjRef +from .pdfexceptions import PDFException from .pdftypes import PDFStream from .pdftypes import dict_value from .pdftypes import list_value from .pdftypes import resolve1 from .pdftypes import stream_value from .psparser import KWD +from .psexceptions import PSEOF, PSTypeError from .psparser import LIT -from .psparser import PSEOF from .psparser import PSKeyword -from .psparser import PSLiteral, PSTypeError +from .psparser import PSLiteral from .psparser import PSStackParser from .psparser import PSStackType from .psparser import keyword_name diff --git a/pdfminer/pdfpage.py b/pdfminer/pdfpage.py index b96a3cac..7df4cf6b 100644 --- a/pdfminer/pdfpage.py +++ b/pdfminer/pdfpage.py @@ -6,8 +6,8 @@ from . import settings from .pdfdocument import PDFDocument, PDFTextExtractionNotAllowed, PDFNoPageLabels from .pdfparser import PDFParser -from .pdftypes import PDFObjectNotFound from .pdftypes import dict_value +from .pdfexceptions import PDFObjectNotFound from .pdftypes import int_value from .pdftypes import list_value from .pdftypes import resolve1 diff --git a/pdfminer/pdfparser.py b/pdfminer/pdfparser.py index 992d8840..b4f2d572 100644 --- a/pdfminer/pdfparser.py +++ b/pdfminer/pdfparser.py @@ -3,16 +3,15 @@ from typing import BinaryIO, TYPE_CHECKING, Optional, Union from . import settings -from .pdftypes import PDFException from .pdftypes import PDFObjRef +from .pdfexceptions import PDFException from .pdftypes import PDFStream from .pdftypes import dict_value from .pdftypes import int_value from .psparser import KWD -from .psparser import PSEOF +from .psexceptions import PSEOF, PSSyntaxError from .psparser import PSKeyword from .psparser import PSStackParser -from .psparser import PSSyntaxError if TYPE_CHECKING: from .pdfdocument import PDFDocument diff --git a/pdfminer/pdftypes.py b/pdfminer/pdftypes.py index 5f302ba3..635c5a66 100644 --- a/pdfminer/pdftypes.py +++ b/pdfminer/pdftypes.py @@ -14,14 +14,12 @@ cast, ) -from . import settings +from . import settings, pdfexceptions from .ascii85 import ascii85decode from .ascii85 import asciihexdecode from .ccitt import ccittfaxdecode from .lzw import lzwdecode -from .psparser import LIT -from .psparser import PSException -from .psparser import PSObject +from .psparser import LIT, PSObject from .runlength import rldecode from .utils import apply_png_predictor @@ -69,24 +67,12 @@ class PDFObject(PSObject): pass -class PDFException(PSException): - pass - - -class PDFTypeError(PDFException): - pass - - -class PDFValueError(PDFException): - pass - - -class PDFObjectNotFound(PDFException): - pass - - -class PDFNotImplementedError(PDFException): - pass +# Adding aliases for these exceptions for backwards compatibility +PDFException = pdfexceptions.PDFException +PDFTypeError = pdfexceptions.PDFTypeError +PDFValueError = pdfexceptions.PDFValueError +PDFObjectNotFound = pdfexceptions.PDFObjectNotFound +PDFNotImplementedError = pdfexceptions.PDFNotImplementedError class PDFObjRef(PDFObject): diff --git a/pdfminer/psexceptions.py b/pdfminer/psexceptions.py new file mode 100644 index 00000000..b8291dc0 --- /dev/null +++ b/pdfminer/psexceptions.py @@ -0,0 +1,18 @@ +class PSException(Exception): + pass + + +class PSEOF(PSException): + pass + + +class PSSyntaxError(PSException): + pass + + +class PSTypeError(PSException): + pass + + +class PSValueError(PSException): + pass diff --git a/pdfminer/psparser.py b/pdfminer/psparser.py index 83d15140..cbaba002 100755 --- a/pdfminer/psparser.py +++ b/pdfminer/psparser.py @@ -18,30 +18,18 @@ Union, ) -from . import settings +from . import settings, psexceptions from .utils import choplist log = logging.getLogger(__name__) -class PSException(Exception): - pass - - -class PSEOF(PSException): - pass - - -class PSSyntaxError(PSException): - pass - - -class PSTypeError(PSException): - pass - - -class PSValueError(PSException): - pass +# Adding aliases for these exceptions for backwards compatibility +PSException = psexceptions.PSException +PSEOF = psexceptions.PSEOF +PSSyntaxError = psexceptions.PSSyntaxError +PSTypeError = psexceptions.PSTypeError +PSValueError = psexceptions.PSValueError class PSObject: @@ -666,7 +654,7 @@ def nextobject(self) -> PSStackEntry[ExtraT]: self.curstack, ) self.do_keyword(pos, token) - raise + raise PSException if self.context: continue else: diff --git a/pdfminer/utils.py b/pdfminer/utils.py index 59cf5cd3..b2a33b80 100644 --- a/pdfminer/utils.py +++ b/pdfminer/utils.py @@ -25,6 +25,8 @@ cast, ) +from .pdfexceptions import PDFTypeError, PDFValueError + if TYPE_CHECKING: from .layout import LTComponent @@ -56,7 +58,7 @@ def __init__(self, filename: FileOrName, *args: Any, **kwargs: Any) -> None: self.file_handler = cast(AnyIO, filename) self.closing = False else: - raise TypeError("Unsupported input type: %s" % type(filename)) + raise PDFTypeError("Unsupported input type: %s" % type(filename)) def __enter__(self) -> AnyIO: return self.file_handler @@ -134,7 +136,7 @@ def apply_png_predictor( """ if bitspercomponent not in [8, 1]: msg = "Unsupported `bitspercomponent': %d" % bitspercomponent - raise ValueError(msg) + raise PDFValueError(msg) nbytes = colors * columns * bitspercomponent // 8 bpp = colors * bitspercomponent // 8 # number of bytes per complete pixel @@ -215,7 +217,7 @@ def apply_png_predictor( raw += bytes((raw_x,)) else: - raise ValueError("Unsupported predictor value: %d" % filter_type) + raise PDFValueError("Unsupported predictor value: %d" % filter_type) buf += raw line_above = raw @@ -360,7 +362,7 @@ def nunpack(s: bytes, default: int = 0) -> int: elif length == 8: return cast(int, struct.unpack(">Q", s)[0]) else: - raise TypeError("invalid length: %d" % length) + raise PDFTypeError("invalid length: %d" % length) PDFDocEncoding = "".join( diff --git a/tests/test_pdfdocument.py b/tests/test_pdfdocument.py index c57126fb..e2643cd7 100644 --- a/tests/test_pdfdocument.py +++ b/tests/test_pdfdocument.py @@ -4,7 +4,8 @@ from pdfminer.pdfdocument import PDFDocument, PDFNoPageLabels from pdfminer.pdfparser import PDFParser -from pdfminer.pdftypes import PDFObjectNotFound, dict_value, int_value +from pdfminer.pdftypes import dict_value, int_value +from pdfminer.pdfexceptions import PDFObjectNotFound from tests.helpers import absolute_sample_path diff --git a/tests/test_pdfminer_psparser.py b/tests/test_pdfminer_psparser.py index 2b4c683e..d11ac39a 100644 --- a/tests/test_pdfminer_psparser.py +++ b/tests/test_pdfminer_psparser.py @@ -1,7 +1,8 @@ import logging from io import BytesIO -from pdfminer.psparser import KWD, LIT, PSBaseParser, PSStackParser, PSEOF +from pdfminer.psparser import KWD, LIT, PSBaseParser, PSStackParser +from pdfminer.psexceptions import PSEOF logger = logging.getLogger(__name__) diff --git a/tools/dumppdf.py b/tools/dumppdf.py index cc8c4558..6e19e275 100755 --- a/tools/dumppdf.py +++ b/tools/dumppdf.py @@ -11,8 +11,18 @@ from pdfminer.pdfdocument import PDFDocument, PDFNoOutlines, PDFXRefFallback from pdfminer.pdfpage import PDFPage from pdfminer.pdfparser import PDFParser -from pdfminer.pdftypes import PDFObjectNotFound, PDFValueError -from pdfminer.pdftypes import PDFStream, PDFObjRef, resolve1, stream_value +from pdfminer.pdftypes import ( + PDFStream, + PDFObjRef, + resolve1, + stream_value, +) +from pdfminer.pdfexceptions import ( + PDFTypeError, + PDFValueError, + PDFObjectNotFound, + PDFIOError, +) from pdfminer.psparser import PSKeyword, PSLiteral, LIT from pdfminer.utils import isnumber @@ -92,7 +102,7 @@ def dumpxml(out: TextIO, obj: object, codec: Optional[str] = None) -> None: out.write("%s" % obj) return - raise TypeError(obj) + raise PDFTypeError(obj) def dumptrailers( @@ -224,7 +234,7 @@ def extract1(objid: int, obj: Dict[str, Any]) -> None: ) path = os.path.join(extractdir, "%.6d-%s" % (objid, filename)) if os.path.exists(path): - raise IOError("file exists: %r" % path) + raise PDFIOError("file exists: %r" % path) print("extracting: %r" % path) os.makedirs(os.path.dirname(path), exist_ok=True) out = open(path, "wb") diff --git a/tools/pdf2txt.py b/tools/pdf2txt.py index 0511b937..fe158593 100755 --- a/tools/pdf2txt.py +++ b/tools/pdf2txt.py @@ -9,6 +9,7 @@ import pdfminer.high_level from pdfminer.layout import LAParams from pdfminer.utils import AnyIO +from pdfminer.pdfexceptions import PDFValueError logging.basicConfig() @@ -43,7 +44,7 @@ def extract_text( **kwargs: Any ) -> AnyIO: if not files: - raise ValueError("Must provide files to work upon!") + raise PDFValueError("Must provide files to work upon!") if output_type == "text" and outfile != "-": for override, alttype in OUTPUT_TYPES: From f9cae1fbf48fcd7f26b7292676414fe42107dce5 Mon Sep 17 00:00:00 2001 From: Bailey Capuano Date: Sun, 7 Jul 2024 16:47:29 -0600 Subject: [PATCH 21/22] Correct name of generated corpus to be properly ingested by ClusterFuzz --- fuzzing/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzzing/build.sh b/fuzzing/build.sh index d2f8f7f1..fb050dd6 100644 --- a/fuzzing/build.sh +++ b/fuzzing/build.sh @@ -6,5 +6,5 @@ for fuzzer in $(find fuzzing -name '*_fuzzer.py');do compile_python_fuzzer "$fuzzer" --collect-all charset_normalizer --hidden-import=_cffi_backend base_name=$(basename "$fuzzer") base_name_no_ext=${base_name%.*} - zip -q $OUT/"$base_name_no_ext".zip $SRC/corpus/* + zip -q $OUT/"${base_name_no_ext}_seed_corpus".zip $SRC/corpus/* done From ee5ef6c8ef767a7f91f5b831f333a8c358d0ec51 Mon Sep 17 00:00:00 2001 From: Bailey Capuano Date: Sun, 7 Jul 2024 16:57:12 -0600 Subject: [PATCH 22/22] Added to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71bb1615..8cf572e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Resolve stream filter parameters ([#906](https://github.com/pdfminer/pdfminer.six/pull/906)) - Reading cmap's with whitespace in the name ([#935](https://github.com/pdfminer/pdfminer.six/pull/935)) - Optimize `apply_png_predictor` by using lists ([#912](https://github.com/pdfminer/pdfminer.six/pull/912)) +- The naming of fuzzing corpora ([#975](https://github.com/pdfminer/pdfminer.six/pull/975)) ## [20231228]