Skip to content

Commit 8cfd915

Browse files
committed
fix #501: parse for entities only once
1 parent 443e8ed commit 8cfd915

3 files changed

Lines changed: 29 additions & 1 deletion

File tree

spec/entities_spec.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,4 +501,28 @@ describe("XMLParser External Entites", function() {
501501
// console.log(output);
502502
expect(output.replace(/\s+/g, "")).toEqual(expected.replace(/\s+/g, ""));
503503
});
504+
505+
it("should replace '<' with '<'", function() {
506+
const xmlData = `<SimpleScalarPropertiesInputOutput>
507+
<stringValue>&amp;lt;</stringValue>
508+
</SimpleScalarPropertiesInputOutput>`;
509+
510+
const expected = {
511+
"SimpleScalarPropertiesInputOutput": {
512+
"stringValue": "&lt;"
513+
}
514+
};
515+
516+
const options = {
517+
attributeNamePrefix: "",
518+
ignoreAttributes: false,
519+
processEntities: true,
520+
// preserveOrder: true
521+
};
522+
const parser = new XMLParser(options);
523+
let result = parser.parse(xmlData);
524+
//console.log(JSON.stringify(result,null,4));
525+
526+
expect(result).toEqual(expected);
527+
});
504528
});

src/xmlparser/OrderedObjParser.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ class OrderedObjParser{
2020
this.tagsNodeStack = [];
2121
this.docTypeEntities = {};
2222
this.lastEntities = {
23-
"amp" : { regex: /&(amp|#38|#x26);/g, val : "&"},
2423
"apos" : { regex: /&(apos|#39|#x27);/g, val : "'"},
2524
"gt" : { regex: /&(gt|#62|#x3E);/g, val : ">"},
2625
"lt" : { regex: /&(lt|#60|#x3C);/g, val : "<"},
2726
"quot" : { regex: /&(quot|#34|#x22);/g, val : "\""},
2827
};
28+
this.ampEntity = { regex: /&(amp|#38|#x26);/g, val : "&"};
2929
this.htmlEntities = {
3030
"space": { regex: /&(nbsp|#160);/g, val: " " },
3131
// "lt" : { regex: /&(lt|#60);/g, val: "<" },
@@ -364,6 +364,7 @@ const parseXml = function(xmlData) {
364364
}
365365

366366
const replaceEntitiesValue = function(val){
367+
367368
if(this.options.processEntities){
368369
for(let entityName in this.docTypeEntities){
369370
const entity = this.docTypeEntities[entityName];
@@ -379,6 +380,7 @@ const replaceEntitiesValue = function(val){
379380
val = val.replace( entity.regex, entity.val);
380381
}
381382
}
383+
val = val.replace( this.ampEntity.regex, this.ampEntity.val);
382384
}
383385
return val;
384386
}

src/xmlparser/XMLParser.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class XMLParser{
4747
throw new Error("Entity value can't have '&'")
4848
}else if(key.indexOf("&") !== -1 || key.indexOf(";") !== -1){
4949
throw new Error("An entity must be set without '&' and ';'. Eg. use '#xD' for '&#xD;'")
50+
}else if(value === "&"){
51+
throw new Error("An entity with value '&' is not permitted");
5052
}else{
5153
this.externalEntities[key] = value;
5254
}

0 commit comments

Comments
 (0)