Skip to content

Multiple segmentation faults in CPython's XML module #160497

Closed as not planned
Closed as not planned

Description

@zahinwahab

Crash report

Bug Description

During differential fuzz testing of CPython and PyPy, we observed segmentation faults in CPython involving several XML-related standard library APIs.

The five cases involve xml.etree.ElementPath.iterfind() and the find(), findall(), findtext(), and iterfind() methods of xml.etree.ElementTree.Element. As, all five cases involve unusually long XPath expressions, ranging from approximately 400,000 to 880,000 characters, we are reporting them together.

Environment

  • CPython: 3.11.11
  • OS: Ubuntu 24.04.3 LTS

Reproduction Cases

The following reproduction programs reconstruct the long XPath strings from the available fuzzing records. Case 2 and 3 shows maximum recursion depth exceeded exception in the newest 3.11.17; rest segmentation faults still exists in 3.11.17.

Case 1: xml.etree.ElementPath.iterfind

import xml.etree.ElementPath as EP
from xml.dom import minidom
element1 = minidom.Element("45")  
prefix = (
    "<function dataclass.<locals>.wrap at 0x72ab51083a60>"
    "<function dataclass.<locals>.wrap at 0x72ab51083a60>"
    "<function dataclass.<locals>.wrap at 0x72ab51083a60>"
    "<function dataclass.<locals>.wrap"
)
pattern = "<function dataclass.<locals>.wrap at 0x72ab51083a60>"
TARGET_LEN = 502_443


arg = prefix
needed = TARGET_LEN - len(arg)
if needed > 0:
    reps = (needed // len(pattern)) + 3
    arg += pattern * reps


arg = arg[:TARGET_LEN]
args = [element1, arg]
print("Length:", len(arg)) 
assert len(arg) == TARGET_LEN
print("Calling ElementPath.iterfind(...) …")
try:
    result = list(EP.iterfind(*args))
    print("Success – result size:", len(result))
except Exception as e:
    print("Exception during iterfind:", e)

Case 2: xml.etree.ElementTree.Element.findall

import xml.etree.ElementTree as ET
tag = "str_969"
attrib = {}
element = ET.Element(tag, attrib)
pattern = (
    "<function no_type_check_decorator.<locals>.wrapped_decorator "
    "at 0x7357ba2d3f60>"
)
TARGET_LEN = 449_520
prefix = (
    "'<function no_type_check_decorator.<locals>.wrapped_decorator at 0x7357ba2d3f60>"
    "<function no_type_check_decorator.<locals>.wrapped_decorator at 0x7357ba2d3f60>"
    "<function no_type_check_decorator.<local"
)
arg = prefix
needed = TARGET_LEN - len(arg)

if needed > 0:
   
    reps = (needed // len(pattern)) + 2
    arg += pattern * reps


arg = arg[:TARGET_LEN]
method_args = [arg]
print("Length of method_args[0]:", len(method_args[0]))  # Should be 449520
try:
    print("Calling findall() ...")
    result = element.findall(method_args[0])
    print("Success:", result)
except Exception as e:
    print("Exception during findall:", e)

Case 3: xml.etree.ElementTree.Element.find

import xml.etree.ElementTree as ET
tag = "str_72"
attrib = {
    "str_622": "str_821",
    "str_783": "str_979",
}
element = ET.Element(tag, attrib)
prefix = (
    "<function no_type_check_decorator.<locals>.wrapped_decorator at 0x77d93df57a60>"
    "<function no_type_check_decorator.<locals>.wrapped_decorator at 0x77d93df57a60>"
    "<function no_type_check_decorator.<locals>.wrapped_decorator at 0x77d93df57a60>"
    "<function no_type_check_decorator.<locals>.wrapped_decorator"
)
pattern = (
    "<function no_type_check_decorator.<locals>.wrapped_decorator "
    "at 0x77d93df57a60>"
)

TARGET_LEN = 404_569
arg = prefix

needed = TARGET_LEN - len(arg)
if needed > 0:
    reps = (needed // len(pattern)) + 3
    arg += pattern * reps
arg = arg[:TARGET_LEN]
method_args = [arg]
print("Length:", len(method_args[0]))  # Should print 404569
assert len(method_args[0]) == TARGET_LEN
print("Calling find() …")
try:
    result = element.find(method_args[0])
    print("find() returned:", result)
except Exception as e:
    print("Exception during find():", e)

Case 4: xml.etree.ElementTree.Element.findtext

import xml.etree.ElementTree as ET
tag = "str_18"
attrib = {
    "str_24": "str_279",
    "str_189": "str_807"
}
element = ET.Element(tag, attrib)
prefix = (
    "+/v/\\U000e0062G\ufffdst\ufffd_128\\U0009f021\\x0b\ufffd\\uffff\ufffd"
    "\\U000e005d\ufffd-1+/v/\\U000e0062G\ufffdst\ufffd_128\\U0009f021\\x0b"
    "\ufffd\\uffff\ufffd\\U000e005d\ufffd-1+/v/\\U000e0062G\ufffdst\ufffd_128"
    "\\U0009f021\\x0b\ufffd\\uffff\ufffd\\U000e005d\ufffd-1+/v/\\U000e0062G"
    "\ufffdst\ufffd_128\\U0009f021\\x0b\ufffd\\uffff\ufffd\\U000e005d\ufffd-1+/v/"
)
pattern = (
    "+/v/\U000e0062G\ufffdst\ufffd_128\U0009f021\x0b\ufffd\uffff\ufffd"
    "\U000e005d\ufffd-1"
)

TARGET_LEN = 459_202
arg = prefix

needed = TARGET_LEN - len(arg)
if needed > 0:
    reps = (needed // len(pattern)) + 3
    arg += pattern * reps

arg = arg[:TARGET_LEN]   
method_args = [arg]
print("Length:", len(method_args[0]))
assert len(method_args[0]) == TARGET_LEN
try:
    print("Calling findtext()...")
    result = element.findtext(method_args[0])
    print("Success:", result)
except Exception as e:
    print("Exception during findtext:", e)

Case 5: xml.etree.ElementTree.Element.iterfind

import xml.etree.ElementTree as ET
tag = "str_288"
attrib = {
    "str_861": "str_965",
    "str_968": "str_343",
    "str_163": "str_4",
    "str_775": "str_468",
    "str_71": "str_347",
}
element = ET.Element(tag, attrib)
pattern = (
    "\rLeve\ufffd\ufffd\U000e0042\ufffd\ufffd\ufffd\ufffd"
    "1\ufffd3\ufffd\ufffd\u202a3+/v9223372036854693041"
)

TARGET_LEN = 879_882
repetitions = (TARGET_LEN // len(pattern)) + 2
big_string = pattern * repetitions
big_string = big_string[:TARGET_LEN]
method_args = [big_string]
print("Length of method_args[0]:", len(method_args[0]))


print("Calling iterfind() ...")
try:
    result = list(element.iterfind(method_args[0]))
    print("Success – result length:", len(result))
except Exception as e:
    print("Exception during iterfind:", e)

CPython versions tested on:

3.11

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

No response

Activity

  1. added
    type-crashA hard crash of the interpreter, possibly with a core dump
    on Oct 23, 2026
  2. encukou commented on Oct 23, 2026

    @encukou
    Member

    None of these crash on 3.12+.
    Python 3.11 now no longer accepts bugfixes, so I'll close this.

  3. zahinwahab commented on Oct 23, 2026

    @zahinwahab
    Author

    Thank you so much for the quick response!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-crashA hard crash of the interpreter, possibly with a core dump

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions