#!/usr/bin/env python
# Test should cause segfault on Linux i386 Python 2.7.3 - 2.7.4
from __future__ import print_function
import sys
import xml.parsers.expat
def start_element(name, attrs):
pass
def end_element(name):
pass
def char_data(data):
pass
ep = None
def instantiate_parser():
"""Create an Expat parser instance (intended for re-use across multiple
calls to its Parse() method) and attach generic delegate methods."""
global ep
try:
ep = xml.parsers.expat.ParserCreate()
ep.StartElementHandler = start_element
ep.EndElementHandler = end_element
ep.CharacterDataHandler = char_data
except xml.parsers.expat.ExpatError as error:
print("An error occurred during Expat set-up. " \
+ "Error ID: " + str(error.code) \
+ ". Error message: " \
+ xml.parsers.expat.ErrorString(error.code), file=sys.stderr)
# We're not actually using this function since we'll crash before it
# gets called...
def destroy_parser():
"""Invoke a final call to the Expat parser's Parse() method to pass the
IsFinal value of True so it will destroy itself."""
global ep
if ep != None:
try:
ep.Parse('', True)
except xml.parsers.expat.ExpatError as error:
print("An error occurred during XML parsing. " \
+ "Error ID: " + str(error.code) \
+ ". Error message: " \
+ xml.parsers.expat.ErrorString(error.code), file=sys.stderr)
finally:
ep = None
def parse_doc(input_string):
"""Accepts a string representing relevant data from an XML file and
initiates the extraction of relevant data via proxy methods."""
global ep
if ep == None:
instantiate_parser()
try:
ep.Parse(input_string, False)
except xml.parsers.expat.ExpatError as error:
print("An error occurred during XML parsing. " \
+ "Error ID: " + str(error.code) \
+ ". Error message: " \
+ xml.parsers.expat.ErrorString(error.code), file=sys.stderr)
print("Line number:", ep.ErrorLineNumber, file=sys.stderr)
small_test_file = \
"""
777
443>
"""
data_size = 248174
large_test_file = \
'' \
+ "\n\n" \
+ "1234\n" * data_size \
+ ''
if __name__ == "__main__":
def lol():
parse_doc(small_test_file) # Initial, successful parse
parse_doc(small_test_file) # First triggering of a parser error
parse_doc(large_test_file) # Subsequent parser error, with more data
destroy_parser()
import threading
for i in xrange(85):
threading.Thread(target=lol).start()