Skip to content

fix: validator; accept XML name characters in entity references - #887

Open
troclaux wants to merge 1 commit into
NaturalIntelligence:masterfrom
troclaux:fix/validator-entity-name-chars
Open

troclaux wants to merge 1 commit into
NaturalIntelligence:masterfrom
troclaux:fix/validator-entity-name-chars

Conversation

@troclaux

@troclaux troclaux commented Oct 7, 2026

Copy link
Copy Markdown

Purpose / Goal

XMLValidator.validate() rejects well-formed documents that contain an entity reference whose name has - or . in it, so parser.parse(xml, true) (validate, then parse) throws on input the parser itself handles fine.

Input

const xml = '<!DOCTYPE doc [<!ENTITY foo-bar "hello">]><a>&foo-bar;</a>';

Expected output

XMLValidator.validate(xml);           // true
new XMLParser().parse(xml, true);     // { a: "hello" }

Actual output (before this change)

XMLValidator.validate(xml);           // { err: { code: "InvalidChar", msg: "char '&' is not expected.", line: 1, col: 46 } }
new XMLParser().parse(xml);           // { a: "hello" }  (without validation)
new XMLParser().parse(xml, true);     // throws

Cause: validateAmpersand in src/validator.js only accepted \w characters in an entity name. Per the XML spec an entity name is a Name, which allows -, ., : and non-ASCII letters after the first character, and DocTypeReader already accepts such names.

Change: validateAmpersand now accepts any XML NameChar (new isNameChar helper in src/util.js, built from the same nameChar set that isName already uses). The existing 20 character limit and the first-character leniency are unchanged, so every input accepted before is still accepted.

Tests: added a spec to spec/validator_spec.js (names with -, ., :, a non-ASCII letter, the DOCTYPE example above, and negative cases for a space, +, and a missing ;). It fails before the change; npm test (333 specs, 0 failures) and npm run test-types pass.

Perf (XMLValidator.validate on a ~270 KB document with many &amp;/&lt;/&#123; references, median of 5 runs of 50): 2.42 ms before, 2.10 ms after. I did not run benchmark/XmlParser.mjs, which needs its own dependency install.

Notes: changelog, version and bundles are left to maintainers per the contributing guide. npm run lint already reports errors on master (and its benchmark/**/*.js glob matches no files); the one new report from this change is the same no-misleading-character-class that src/util.js already triggers for nameStartChar.

Type

  • Bug Fix
  • Refactoring / Technology upgrade
  • New Feature

validateAmpersand only accepted \w characters, so a valid reference such as &foo-bar; made validate() (and parse(xml, true)) fail with InvalidChar even though the parser itself resolves it. Accept any XML NameChar instead; the 20 character limit is unchanged.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant