Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[quality] the decimal out-of-range entity guard in decodeEntities is unpinned while its hex twin is tested

Closed Beginner friendly
#570 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
75/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
javascript
Domain
security, testing

Research direction

Look at tests/svg-active-content.test.mjs to see the existing test for out-of-range hex entities. Add a similar test for a decimal entity above 0x10ffff (e.g., �). Verify that decodeEntities in scripts/lib/svg-active-content.mjs leaves the literal unchanged and that stripActiveContent reports nothing removed. Run the test suite to confirm coverage.

Written by the indexing model from the issue text.

Description

agent/quality hive/hosted-available-lke648397-260827-5n31 quality testing

Finding

decodeEntities in scripts/lib/svg-active-content.mjs has two numeric-entity
callbacks, and each guards String.fromCodePoint against an out-of-range
codepoint before calling it:

.replace(/&#x([0-9a-f]+);?/gi, (match, hex) => {
  const code = Number.parseInt(hex, 16);
  return Number.isFinite(code) && code <= 0x10ffff
    ? String.fromCodePoint(code)
    : match;
})
.replace(/&#(\d+);?/g, (match, dec) => {
  const code = Number.parseInt(dec, 10);
  return Number.isFinite(code) && code <= 0x10ffff
    ? String.fromCodePoint(code)
    : match;
})

The hex guard is pinned by leaves an out-of-range hex entity literal rather than forming a scheme, added in #541. The decimal guard is not: no test
supplies a decimal entity above 0x10ffff, so its false arm has never run.

Evidence

Verified at rev b99ebd0 on node v26.8.2:

npm run test:unit -- --experimental-test-coverage \
  --test-coverage-include='scripts/lib/svg-active-content.mjs' \
  --test-reporter=lcov --test-reporter-destination=cov.info

scripts/lib/svg-active-content.mjs reports 100.00% lines / 100.00% funcs /
84.44% branches, and cov.info carries BRDA with taken=0 at line 67 — the
code <= 0x10ffff false arm of the decimal callback.

Why it matters

The guard is not cosmetic. Without it the callback crashes on input an attacker
controls:

$ node -e "String.fromCodePoint(1114112)"
RangeError: Invalid code point 1114112

decodeEntities runs on every attribute value of every SVG imported from a
third-party repository, so an asset containing &#1114112; would take the
validator down with an uncaught RangeError rather than being reported. The
guard turns that into "leave the entity literal, and it forms no scheme".
Nothing currently stops that guard being removed as redundant, because the
suite stays green when it is.

An out-of-range decimal entity is also a plausible obfuscation attempt in its
own right, and the correct outcome — the literal &#1114112; survives and is
not itself read as a scheme — is worth stating.

Recommendation

Add the decimal twin of the existing hex test to
tests/svg-active-content.test.mjs, asserting both that detection stays quiet
and that stripActiveContent returns the source unchanged with an empty
removed. No production code changes.

  • a decimal numeric entity above 0x10ffff is left literal by decodeEntities
  • the surviving literal entity does not itself read as an active scheme
  • stripActiveContent leaves such a payload untouched and reports nothing removed

Priority

  • Impact: medium — an unpinned crash guard on an untrusted-input path
  • Effort: low — one test, no production change

Filed by quality agent (hold-gated mode)

🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5n31 | SHA: b99ebd0

— hive: agent=quality backend=copilot model=claude-opus-5 copilot=1.0.88

Dominant language
JavaScript
Stars
0
Forks
2
Avg merge
17h
Merged PRs (30d)
587

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from cncf/endusers

All issues in cncf/endusers

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.