Skip to content

Commit

Permalink
replaced jPath '.' with '|', ran test cases with new example
Browse files Browse the repository at this point in the history
  • Loading branch information
varad11 committed May 22, 2023
1 parent 88d13cc commit 3f4d56c
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 11 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
Note: If you find missing information about particular minor version, that version must have been changed without any functional change in this library.

**4.2.3 / 2023-05-23**
* fix #573: unopened closing tags should be ignored instead of throwing "*Cannot read properties of undefined*" exception.

**4.2.2 / 2023-04-18**
* fix #562: fix unpaired tag when it comes in last of a nested tag. Also throw error when unpaired tag is used as closing tag

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fast-xml-parser",
"version": "4.2.2",
"version": "4.2.3",
"description": "Validate XML, Parse XML, Build XML without C/C++ based libraries",
"main": "./src/fxp.js",
"scripts": {
Expand Down
41 changes: 41 additions & 0 deletions spec/xmlParser_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1098,4 +1098,45 @@ describe("XMLParser", function() {
let result = parser.parse(xmlData);
expect(result).toEqual(expected);
});

it("should ignore closing tags without an opening tag", function() {
const xmlData = `<rootNode>
<parentTag attr='my attr'>
<childTag>Hello</childTag>
</parentTag>
<parentTag attr='my attr'>
</childTag> <!-- unopened closing tag -->
</childTag> <!-- unopened closing tag -->
</parentTag>
</parentTag> <!-- unopened closing tag -->
<parentTag attr='my attr'>
<childTag>World</childTag>
</parentTag>
</rootNode>`;
const options = {
ignoreAttributes: false,
preserveOrder: false,
alwaysCreateTextNode: false
};
const expected = {
"rootNode": {
"parentTag": [
{
"childTag": "Hello",
"@_attr": "my attr"
},
{
"@_attr": "my attr"
},
{
"childTag": "World",
"@_attr": "my attr"
}
]
}
};
const parser = new XMLParser(options);
let result = parser.parse(xmlData);
expect(result).toEqual(expected);
});
});
23 changes: 13 additions & 10 deletions src/xmlparser/OrderedObjParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,20 +207,23 @@ const parseXml = function(xmlData) {
}

//check if last tag of nested tag was unpaired tag
const lastTagName = jPath.substring(jPath.lastIndexOf(".")+1);
const lastTagName = jPath.substring(jPath.lastIndexOf("|")+1);
if(tagName && this.options.unpairedTags.indexOf(tagName) !== -1 ){
throw new Error(`Unpaired tag can not be used as closing tag: </${tagName}>`);
}
let propIndex = 0
if(lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1 ){
propIndex = jPath.lastIndexOf('.', jPath.lastIndexOf('.')-1)
propIndex = jPath.lastIndexOf('|', jPath.lastIndexOf('|')-1)
this.tagsNodeStack.pop();
}else{
propIndex = jPath.lastIndexOf(".");
}
jPath = jPath.substring(0, propIndex);
propIndex = jPath.lastIndexOf("|");
}
if(lastTagName === tagName) {
//update path and pop out node only when the closing tag matches with opening tag. This condition will thus ignore unopened closing tags.
jPath = jPath.substring(0, propIndex);

currentNode = this.tagsNodeStack.length ? this.tagsNodeStack.pop() : currentNode;//avoid recursion, set the parent tag scope
currentNode = this.tagsNodeStack.pop();//avoid recursion, set the parent tag scope
}
textData = "";
i = closeIndex;
} else if( xmlData[i+1] === '?') {
Expand Down Expand Up @@ -300,10 +303,10 @@ const parseXml = function(xmlData) {
const lastTag = currentNode;
if(lastTag && this.options.unpairedTags.indexOf(lastTag.tagname) !== -1 ){
currentNode = this.tagsNodeStack.pop();
jPath = jPath.substring(0, jPath.lastIndexOf("."));
jPath = jPath.substring(0, jPath.lastIndexOf("|"));
}
if(tagName !== xmlObj.tagname){
jPath += jPath ? "." + tagName : tagName;
jPath += jPath ? "|" + tagName : tagName;
}
if (this.isItStopNode(this.options.stopNodes, jPath, tagName)) { //TODO: namespace
let tagContent = "";
Expand Down Expand Up @@ -332,7 +335,7 @@ const parseXml = function(xmlData) {
tagContent = this.parseTextData(tagContent, tagName, jPath, true, attrExpPresent, true, true);
}

jPath = jPath.substr(0, jPath.lastIndexOf("."));
jPath = jPath.substr(0, jPath.lastIndexOf("|"));
childNode.add(this.options.textNodeName, tagContent);

this.addChild(currentNode, childNode, jPath)
Expand All @@ -355,7 +358,7 @@ const parseXml = function(xmlData) {
childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName);
}
this.addChild(currentNode, childNode, jPath)
jPath = jPath.substr(0, jPath.lastIndexOf("."));
jPath = jPath.substr(0, jPath.lastIndexOf("|"));
}
//opening tag
else{
Expand Down

0 comments on commit 3f4d56c

Please sign in to comment.