From e8f4b47d590aae7cbdaa203d08d20069d1b9d42a Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Fri, 4 Jan 2019 11:37:44 +0100 Subject: [PATCH] Prevent errors, in `SimpleXMLParser.onEndElement`, when the stack has already been completely parsed (issue 10410) The error was triggered for a particular set of metadata, where an end tag was encountered without the corresponding begin tag being present in the data. (The patch also fixes a minor oversight, from a recent PR, in the `SimpleDOMNode.nextSibling` method.) --- src/display/xml_parser.js | 8 +++++++- test/unit/metadata_spec.js | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/display/xml_parser.js b/src/display/xml_parser.js index 03f64cd3d..38de48cbe 100644 --- a/src/display/xml_parser.js +++ b/src/display/xml_parser.js @@ -287,6 +287,9 @@ class SimpleDOMNode { return undefined; } const index = childNodes.indexOf(this); + if (index === -1) { + return undefined; + } return childNodes[index + 1]; } @@ -364,8 +367,11 @@ class SimpleXMLParser extends XMLParserBase { } onEndElement(name) { - this._currentFragment = this._stack.pop(); + this._currentFragment = this._stack.pop() || []; const lastElement = this._currentFragment[this._currentFragment.length - 1]; + if (!lastElement) { + return; + } for (let i = 0, ii = lastElement.childNodes.length; i < ii; i++) { lastElement.childNodes[i].parentNode = lastElement; } diff --git a/test/unit/metadata_spec.js b/test/unit/metadata_spec.js index d5e524c07..01a992702 100644 --- a/test/unit/metadata_spec.js +++ b/test/unit/metadata_spec.js @@ -146,4 +146,26 @@ describe('metadata', function() { expect(metadata.getAll()).toEqual({ 'dc:title': '\'Foo bar baz\'', }); }); + + it('should gracefully handle unbalanced end tags (issue 10410)', function() { + const data = '' + + '' + + '' + + 'Soda PDF 5' + + '' + + '2018-10-02T08:14:49-05:00' + + 'Soda PDF 5' + + '2018-10-02T08:14:49-05:00 ' + + '2018-10-02T08:14:49-05:00' + + '' + + 'uuid:00000000-1c84-3cf9-89ba-bef0e729c831' + + '' + + ''; + const metadata = new Metadata(data); + + expect(isEmptyObj(metadata.getAll())).toEqual(true); + }); });