Merge pull request #21692 from calixteman/fix/quad-regex-xml-entities

Exclude "&" from the XML entity names
This commit is contained in:
Tim van der Meij 2026-08-02 22:24:11 +02:00 committed by GitHub
commit ec691130e6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 1 deletions

View File

@ -49,7 +49,8 @@ function isWhitespaceString(s) {
class XMLParserBase {
static get _entityRegex() {
return shadow(this, "_entityRegex", /&(?:#x([^;]+)|#([^;]+)|([^;]+));/g);
// Entity references cannot contain "&", keeping the scan linear.
return shadow(this, "_entityRegex", /&(?:#x([^;&]+)|#([^;&]+)|([^;&]+));/g);
}
_resolveEntities(s) {

View File

@ -153,4 +153,33 @@ describe("XML", function () {
["foo", ""],
]);
});
describe("entities", function () {
const parseText = xml =>
new SimpleXMLParser({}).parseFromString(xml).documentElement.textContent;
it("should resolve the entities", function () {
expect(
parseText("<a>&lt;b&gt; &amp; &quot;c&quot; &apos;d&apos;</a>")
).toEqual(`<b> & "c" 'd'`);
expect(parseText("<a>&#65;&#x42;</a>")).toEqual("AB");
});
it("should keep the unresolved entities as-is", function () {
expect(parseText("<a>&unknown; a&b;c</a>")).toEqual("&unknown; a&b;c");
});
it("should resolve an entity preceded by a bare ampersand", function () {
expect(parseText("<a>AT&T &amp; Co</a>")).toEqual("AT&T & Co");
expect(parseText("<a>&&amp;</a>")).toEqual("&&");
});
it("should handle a long run of ampersands efficiently", function () {
const text = "&".repeat(100000);
const startTime = performance.now();
expect(parseText(`<a>${text}</a>`)).toEqual(text);
expect(performance.now() - startTime).toBeLessThan(1000);
});
});
});