Closed general

Lint HTML entities in page briefs (they render literally)

Colby Knox · 2mo ago ·closed by Colby Knox

Spotted while screenshot-verifying an unrelated change. kcknox/ws2812b-2020 displays its brief as:

Worldsemi · Intelligent Control LED · 2020 (2.0 × 2.0mm) · Built-in IC + RGB dies

with a literal × on the page instead of a multiplication sign.

The escaping is not the bug. The stored brief genuinely contains the seven characters × as text, and escapeHtml correctly turns that into × so it renders as written. Decoding entities before display would be the wrong fix: escaping is what stops a brief from injecting markup, and making it entity-aware reintroduces exactly the ambiguity it exists to remove.

The bug is upstream, in whatever wrote the brief. Something generating component page metadata emitted an HTML entity where it meant a character, probably because the source it scraped was HTML. Any publisher hand-writing &, <,   or × hits the same thing.

Ask

Lint it at publish rather than fixing pages one at a time. A brief, title, or tag containing what looks like an HTML entity is almost always a mistake, and the publisher is the only one who can say what character they meant.

Suggested shape, matching the existing publish lints:

  • On publish, scan title, brief, and tags for &(#\d+|#x[0-9a-f]+|[a-z]+);
  • Warn (do not block): BRIEF_HTML_ENTITY, naming the entity found and the character it probably means
  • Include the fix in the hint, since the publisher has the source in front of them: "write × directly; briefs are plain text and are escaped on render"

Blocking would be wrong: & legitimately appears in prose, and a false positive that refuses a publish is worse than a literal entity on a page.

Also worth doing, separately

A one-off sweep for existing pages whose stored title/brief matches that pattern. I have not run it, so I do not know whether this is one page or fifty. Worth measuring before deciding whether it needs a data migration or just the lint going forward.

1 Reply

Colby Knox · 2mo ago

Shipped. METADATA_HTML_ENTITY is live on prod and firing.

I measured before deciding, as the filing said to: 12 pages out of 955, and only two entities involved.

pages entity owner
11 × @aravk (the IN-S42/IN-S63 LED series, plus ws2812b-2020)
1 · adom/feeder-reader

So this is a narrow problem, not a systemic one.

Where the bad text actually lives, which changed my plan. I assumed the database, and it is not: the entity is in each page's page.json, and the database brief is derived from it on every publish. Fixing the database would have looked like a fix and then been silently reverted by the next publish. The manifest is the only durable place, and those are the publishers' own repos, so this is theirs to change rather than mine.

That makes the lint the whole fix rather than half of it, since it is what puts the message in front of the person who can act on it.

What it does: on any page read, metadata carrying a named, decimal, or hex character reference produces a warning naming the character you probably meant.

Metadata contains HTML entity that will display literally: × (write ×).
These fields are plain text and are escaped when rendered.
Write the character directly in the manifest.

Two deliberate non-choices.

It does not decode entities on render. That would have been the smallest patch and the wrong one: escaping is exactly what stops a brief injecting markup, and making it entity-aware reintroduces the ambiguity it exists to remove.

It warns rather than blocks. & is ordinary prose, and a lint that refuses a publish over R&D teaches people to ignore lints. Tests pin the false-positive cases specifically: R&D, AT&T, Tom & Jerry, query strings, and an unterminated &amp with no semicolon.

@aravk your 11 component pages currently display 1.0 × 0.5mm in their briefs where they mean 1.0 × 0.5mm. The fix is one character in each page.json's brief, and you will now get the warning on your next publish either way. Whatever generated those briefs looks like it was reading HTML, so it is worth fixing at the generator rather than 11 times by hand.

Log in to reply.