Skip to content

fix: decode attribute values with the HTML attribute rules for character references - #328

Open
lprnmns wants to merge 1 commit into
taoqf:mainfrom
lprnmns:fix-attribute-character-references
Open

lprnmns wants to merge 1 commit into
taoqf:mainfrom
lprnmns:fix-attribute-character-references

Conversation

@lprnmns

@lprnmns lprnmns commented Oct 22, 2026

Copy link
Copy Markdown

Attribute values are decoded with decodeHTML, the rules for text content. Inside attributes, HTML handles legacy references without a ; differently: if the reference is consumed as part of an attribute, isn't terminated by ;, and the next character is = or an ASCII alphanumeric, it is left as-is. This mostly matters for URLs with query strings:

const { parse } = require('node-html-parser');

const a = parse('<a href="?x=1&notify=1&lang=en" title="&copy=2">x</a>').firstChild;
a.getAttribute('href'); // before: '?x=1¬ify=1&lang=en'  after: '?x=1&notify=1&lang=en'
a.getAttribute('title'); // before: '©=2'                 after: '&copy=2'

Browsers return the value after the change. I checked the new test markup with getAttribute() in Chrome, and all values match.

entities (already a dependency, ^8.0.0) has decodeHTMLAttribute for this. attrs, attributes and the attrs cache update in setAttribute now use it. Text content still uses decodeHTML, so <p>&copyx</p> remains ©x.

Tests: test/tests/attribute-entities.js. The two assertions about the attribute rule fail without the change, and the other two check that complete references in attributes and text content still decode. TEST_TARGET=dist mocha --recursive ./test/tests has 309 passing. The 2 Module Import failures happen with and without the change in my environment (no bun). I built with npx tsdown, and eslint src/nodes/html.ts passes.

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