Merge pull request #21682 from calixteman/fix/xml-invalid-char-ref

Don't throw on an invalid XML character reference
This commit is contained in:
Tim van der Meij 2026-08-02 12:26:49 +02:00 committed by GitHub
commit 5dc1d0c5d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 6 deletions

View File

@ -53,12 +53,12 @@ class XMLParserBase {
} }
_resolveEntities(s) { _resolveEntities(s) {
return s.replaceAll(XMLParserBase._entityRegex, (_, hex, dec, entity) => { return s.replaceAll(XMLParserBase._entityRegex, (all, hex, dec, entity) => {
if (hex) { if (hex || dec) {
return String.fromCodePoint(parseInt(hex, 16)); const code = hex ? parseInt(hex, 16) : parseInt(dec, 10);
} // An out-of-range or unparsable code point is kept as-is, since
if (dec) { // `String.fromCodePoint` would throw on it.
return String.fromCodePoint(parseInt(dec, 10)); return code >= 0 && code <= 0x10ffff ? String.fromCodePoint(code) : all;
} }
switch (entity) { switch (entity) {
case "lt": case "lt":

View File

@ -109,6 +109,27 @@ describe("XML", function () {
}); });
}); });
describe("character references", function () {
const parseText = xml =>
new SimpleXMLParser({}).parseFromString(xml).documentElement.textContent;
it("should resolve the valid ones", function () {
expect(parseText("<a>&#65;&#x42;&#x1F602;&#0;&#x10FFFF;</a>")).toEqual(
"AB\u{1F602}\0\u{10FFFF}"
);
});
it("should keep the invalid ones as-is", function () {
// These must not throw: `String.fromCodePoint` rejects anything which
// isn't a code point.
expect(parseText("<a>&#xZZ;</a>")).toEqual("&#xZZ;");
expect(parseText("<a>&#zz;</a>")).toEqual("&#zz;");
expect(parseText("<a>&#x110000;</a>")).toEqual("&#x110000;");
expect(parseText("<a>&#1114112;</a>")).toEqual("&#1114112;");
expect(parseText("<a>&#-1;</a>")).toEqual("&#-1;");
});
});
it("should parse processing instructions", function () { it("should parse processing instructions", function () {
const xml = ` const xml = `
<a> <a>