From 42e1b213561b3952e42321218ae87bc1108cdf4a Mon Sep 17 00:00:00 2001 From: John Evans Date: Wed, 12 Mar 2014 20:50:42 -0400 Subject: [PATCH] Should not raise an exception during parsing of XML box. #184 --- glymur/jp2box.py | 15 +++++++++------ glymur/test/test_codestream.py | 2 +- glymur/test/test_jp2box_xml.py | 17 +++++++++++++++++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/glymur/jp2box.py b/glymur/jp2box.py index c309a26..5dba568 100644 --- a/glymur/jp2box.py +++ b/glymur/jp2box.py @@ -2631,19 +2631,22 @@ class XMLBox(Jp2kBox): read_buffer = fptr.read(num_bytes) try: text = read_buffer.decode('utf-8') - except UnicodeDecodeError as ude: + except UnicodeDecodeError as err: # Possibly bad string of bytes to begin with. # Try to search for -1: - text = read_buffer[decl_start:].decode('utf-8') - else: - raise + if decl_start <= -1: + msg = 'A problem was encountered while parsing an XML box:' + msg += '\n\n\t"{0}"\n\nNo XML was retrieved.' + warnings.warn(msg.format(str(err))) + return XMLBox(xml=None, length=length, offset=offset) + + text = read_buffer[decl_start:].decode('utf-8') # Let the user know that the XML box was problematic. msg = 'A UnicodeDecodeError was encountered parsing an XML box at ' msg += 'byte position {0} ({1}), but the XML was still recovered.' - msg = msg.format(offset, ude.reason) + msg = msg.format(offset, err.reason) warnings.warn(msg, UserWarning) # Strip out any trailing nulls, as they can foul up XML parsing. diff --git a/glymur/test/test_codestream.py b/glymur/test/test_codestream.py index 6e5cc43..ce03ef7 100644 --- a/glymur/test/test_codestream.py +++ b/glymur/test/test_codestream.py @@ -40,7 +40,7 @@ class TestCodestream(unittest.TestCase): Jp2k(filename) else: with self.assertWarns(UserWarning): - Jp2k(jfile) + Jp2k(filename) @unittest.skipIf(OPJ_DATA_ROOT is None, diff --git a/glymur/test/test_jp2box_xml.py b/glymur/test/test_jp2box_xml.py index facc4df..9194a49 100644 --- a/glymur/test/test_jp2box_xml.py +++ b/glymur/test/test_jp2box_xml.py @@ -39,6 +39,7 @@ from glymur.jp2box import ColourSpecificationBox, ContiguousCodestreamBox from glymur.jp2box import FileTypeBox, ImageHeaderBox, JP2HeaderBox from glymur.jp2box import JPEG2000SignatureBox +from .fixtures import OPJ_DATA_ROOT, opj_data_file @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") class TestXML(unittest.TestCase): @@ -93,6 +94,22 @@ class TestXML(unittest.TestCase): def tearDown(self): os.unlink(self.xmlfile) + def test_invalid_utf8(self): + """Bad byte sequence that cannot be parsed.""" + filename = opj_data_file(os.path.join('input', + 'nonregression', + '26ccf3651020967f7778238ef5af08af.SIGFPE.d25.527.jp2')) + if sys.hexversion < 0x03000000: + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + jp2 = Jp2k(filename) + else: + with self.assertWarns(UserWarning): + jp2 = Jp2k(filename) + + self.assertIsNone(jp2.box[3].box[1].box[1].xml) + + def test_negative_file_and_xml(self): """The XML should come from only one source.""" xml_object = ET.parse(self.xmlfile)