From f510ebcdc133c10a359369e53a9e42e66e354520 Mon Sep 17 00:00:00 2001 From: Adam Korczynski Date: Fri, 10 Apr 2026 18:35:24 +0100 Subject: [PATCH] Add fuzzer for expat module --- Makefile | 7 +++++-- expat.py | 38 ++++++++++++++++++++++++++++++++++++++ fuzz_targets.txt | 1 + 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 expat.py diff --git a/Makefile b/Makefile index 9103a1c..4946e38 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ -all : fuzzer-html fuzzer-email fuzzer-httpclient fuzzer-json fuzzer-difflib fuzzer-csv fuzzer-decode fuzzer-ast fuzzer-tarfile fuzzer-tarfile-hypothesis fuzzer-zipfile fuzzer-zipfile-hypothesis fuzzer-re fuzzer-configparser fuzzer-tomllib fuzzer-plistlib fuzzer-xml fuzzer-zoneinfo +all : fuzzer-html fuzzer-email fuzzer-httpclient fuzzer-json fuzzer-difflib fuzzer-csv fuzzer-decode fuzzer-ast fuzzer-tarfile fuzzer-tarfile-hypothesis fuzzer-zipfile fuzzer-zipfile-hypothesis fuzzer-re fuzzer-configparser fuzzer-tomllib fuzzer-plistlib fuzzer-xml fuzzer-zoneinfo fuzzer-expat PYTHON_CONFIG_PATH=$(CPYTHON_INSTALL_PATH)/bin/python3-config CXXFLAGS += $(shell $(PYTHON_CONFIG_PATH) --cflags) -LDFLAGS += -rdynamic $(shell $(PYTHON_CONFIG_PATH) --ldflags --embed) +LDFLAGS += -rdynamic $(shell $(PYTHON_CONFIG_PATH) --ldflags --embed) $(CPYTHON_MODLIBS) -Wl,--allow-multiple-definition fuzzer-html: clang++ $(CXXFLAGS) $(LIB_FUZZING_ENGINE) -std=c++17 fuzzer.cpp -DPYTHON_HARNESS_PATH="\"html.py\"" -ldl $(LDFLAGS) -o fuzzer-html @@ -40,3 +40,6 @@ fuzzer-xml: clang++ $(CXXFLAGS) $(LIB_FUZZING_ENGINE) -std=c++17 fuzzer.cpp -DPYTHON_HARNESS_PATH="\"xml.py\"" -ldl $(LDFLAGS) -o fuzzer-xml fuzzer-zoneinfo: clang++ $(CXXFLAGS) $(LIB_FUZZING_ENGINE) -std=c++17 fuzzer.cpp -DPYTHON_HARNESS_PATH="\"zoneinfo.py\"" -ldl $(LDFLAGS) -o fuzzer-zoneinfo + +fuzzer-expat: + clang++ $(CXXFLAGS) $(LIB_FUZZING_ENGINE) -std=c++17 fuzzer.cpp -DPYTHON_HARNESS_PATH="\"expat.py\"" -ldl $(LDFLAGS) -o fuzzer-expat diff --git a/expat.py b/expat.py new file mode 100644 index 0000000..f4c59da --- /dev/null +++ b/expat.py @@ -0,0 +1,38 @@ +from fuzzeddataprovider import FuzzedDataProvider +from xml.parsers import expat +import io + +ENCODINGS = [None, "utf-8", "iso-8859-1"] + + +# Fuzzes the expat XML parser (Modules/expat/xmlparse.c, Modules/pyexpat.c). +# Creates a parser with a fuzzed encoding selection (None, UTF-8, +# ISO-8859-1), installs handlers for elements, character data, PIs, +# comments, and CDATA sections, then parses fuzzed bytes via Parse() +# or ParseFile(). +def FuzzerRunOne(FuzzerInput): + if len(FuzzerInput) < 1 or len(FuzzerInput) > 0x10000: + return + fdp = FuzzedDataProvider(FuzzerInput) + use_parse_file = fdp.ConsumeBool() + encoding = fdp.PickValueInList(ENCODINGS) + try: + p = expat.ParserCreate(encoding) + p.StartElementHandler = lambda name, attrs: None + p.EndElementHandler = lambda name: None + p.CharacterDataHandler = lambda data: None + p.ProcessingInstructionHandler = lambda target, data: None + p.CommentHandler = lambda data: None + p.StartCdataSectionHandler = lambda: None + p.EndCdataSectionHandler = lambda: None + p.DefaultHandler = lambda data: None + + data = fdp.ConsumeBytes(fdp.remaining_bytes()) + if use_parse_file: + p.ParseFile(io.BytesIO(data)) + else: + p.Parse(data, True) + except expat.ExpatError: + pass + except Exception: + pass diff --git a/fuzz_targets.txt b/fuzz_targets.txt index 8710a5f..8e1cf23 100644 --- a/fuzz_targets.txt +++ b/fuzz_targets.txt @@ -4,6 +4,7 @@ csv csv.py decode decode.py difflib difflib.py email email.py +expat expat.py html html.py httpclient httpclient.py json json.py