Repository navigation
Conversation
onStartElement attaches an internal parent back-reference (xml2js.js:250)
that onEndElement removes when addParent is false. For an unclosed tag
onEndElement never runs, so the reference survives into the returned
object:
convert.xml2json('<a>')
// TypeError: Converting circular structure to JSON
convert.xml2js('<a>').elements[0].parent === result // true
That also contradicts the README, which documents `parent` as appearing
only when addParent is true.
The underlying sax error cannot surface: "Unclosed root tag" is raised
inside end(), after write()'s entry-time error check, and onError discards
it. Hence the asymmetry where `<a></b>` throws a clean "Unmatched closing
tag" but `<a>` does not.
Unwinds anything left open after parsing, mirroring the cleanup already in
onEndElement. Deliberately conservative: it preserves the lenient
"don't throw on unclosed tags" behaviour rather than changing onError, so
it is not a breaking change.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #223.
An unclosed tag left the parser's internal
parentback-reference attached to the returned object, so the result was circular:That also contradicts the README, which documents
parentas appearing only "by setting{addParent: true}".Cause
lib/xml2js.js:250attaches the reference with the comment "will be deleted in onEndElement() if !options.addParent".onEndElementis the only place that removes it, and it never runs for a tag that is never closed.The sax error that should have surfaced can't: "Unclosed root tag" is raised inside
end(), afterwrite()'s entry-time error check, andonError(line 312) iserror.note = error, which discards it. Hence the asymmetry —<a></b>throws a cleanUnmatched closing tag: bbecause that fires duringwrite(), while<a>does not.The change
Unwinds anything left open after parsing, mirroring the cleanup already in
onEndElement.Deliberately conservative: it preserves the library's lenient "don't throw on unclosed tags" behaviour rather than touching
onError, so nothing that parses today starts throwing. It terminates safely if the chain is broken, andaddParent: truestill attachesparentexactly as documented.Tests
Existing suite unchanged: 2363 specs, 0 failures. Three specs added, covering the leak, serialisability, and that
addParent: truestill works — 2366 total.Confirmed they catch it. Reverting only
lib/xml2js.js:Note
Truncated XML is ordinary production input — a cut-off feed, a partial upload, a socket closed mid-response. The current failure surfaces as a
JSON.stringifyerror far from the parse, or as an object that silently breaks deep equality, structured cloning andres.json().