Skip to content

Commit bd26122

Browse files
committed
check for entitiy expansion for lastEntities and html entities too
1 parent 7e70dd8 commit bd26122

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

spec/html_spec.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,23 @@ describe("XMLParser", function () {
7979
output = output.replace('₹', '&inr;');
8080
expect(output.replace(/\s+/g, "")).toEqual(html.replace(/\s+/g, ""));
8181
});
82+
83+
it("should throw error for html entities", function () {
84+
const entity = 'A'.repeat(30);
85+
const xmlData = `<root>${entity}</root>`;
86+
87+
const options = {
88+
htmlEntities: true,
89+
processEntities: {
90+
enabled: true,
91+
maxTotalExpansions: 20,
92+
}
93+
};
94+
const parser = new XMLParser(options);
95+
96+
expect(function () {
97+
const result = parser.parse(xmlData);
98+
console.log(JSON.stringify(result, null, 4));
99+
}).toThrowError(/Entity expansion limit exceeded: 30 > 20/);
100+
});
82101
});

src/xmlparser/OrderedObjParser.js

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ function replaceEntitiesValue(val, tagName, jPath) {
621621
}
622622

623623
// Replace DOCTYPE entities
624-
for (let entityName in this.docTypeEntities) {
624+
for (const entityName of Object.keys(this.docTypeEntities)) {
625625
const entity = this.docTypeEntities[entityName];
626626
const matches = val.match(entity.regx);
627627

@@ -653,19 +653,38 @@ function replaceEntitiesValue(val, tagName, jPath) {
653653
}
654654
}
655655
}
656-
if (val.indexOf('&') === -1) return val; // Early exit
657-
658656
// Replace standard entities
659-
for (let entityName in this.lastEntities) {
657+
for (const entityName of Object.keys(this.lastEntities)) {
660658
const entity = this.lastEntities[entityName];
659+
const matches = val.match(entity.regex);
660+
if (matches) {
661+
this.entityExpansionCount += matches.length;
662+
if (entityConfig.maxTotalExpansions &&
663+
this.entityExpansionCount > entityConfig.maxTotalExpansions) {
664+
throw new Error(
665+
`Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}`
666+
);
667+
}
668+
}
661669
val = val.replace(entity.regex, entity.val);
662670
}
663-
if (val.indexOf('&') === -1) return val; // Early exit
671+
if (val.indexOf('&') === -1) return val;
664672

665673
// Replace HTML entities if enabled
666674
if (this.options.htmlEntities) {
667-
for (let entityName in this.htmlEntities) {
675+
for (const entityName of Object.keys(this.htmlEntities)) {
668676
const entity = this.htmlEntities[entityName];
677+
const matches = val.match(entity.regex);
678+
if (matches) {
679+
//console.log(matches);
680+
this.entityExpansionCount += matches.length;
681+
if (entityConfig.maxTotalExpansions &&
682+
this.entityExpansionCount > entityConfig.maxTotalExpansions) {
683+
throw new Error(
684+
`Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}`
685+
);
686+
}
687+
}
669688
val = val.replace(entity.regex, entity.val);
670689
}
671690
}

0 commit comments

Comments
 (0)