Skip to content

fix(apl): escape validation text before it becomes tooltip HTML - #1536

Merged
1337LutZ merged 1 commit into
masterfrom
fix/apl-validation-tooltip-escaping
Sep 9, 2026
Merged

1337LutZ merged 1 commit into
masterfrom
fix/apl-validation-tooltip-escaping

Conversation

@1337LutZ

@1337LutZ 1337LutZ commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

The problem

APL validation messages are rendered as HTML, and they are not all authored by us.

ui/index.ts sets allowHTML: true as a global tippy default, and
ListPicker.makeListItemValidations builds its tooltip body by interpolating each
validation straight into <li>${v}</li>. The sim formats user-supplied names into those
messages — apl_action_group_reference.go does it for a missing group name, and
apl_values_operators.go for variable names.

Rotations are shared by link and imported as JSON, so a rotation carrying markup in a group
or variable name has that markup rendered in the reader's browser as soon as the warning
tooltip appears. The reader does not have to do anything except open the rotation and hover
a warning.

The fix

Escape the message before it is interpolated.

This is safe to do late, after ActionId.replaceAllInString, because that call substitutes
spell names as plain text — it injects no markup of its own. The only markup left in the
string is the <p>/<ul>/<li> wrapper we write ourselves, which is built outside the
escaped span.

One helper and one call site.

Notes

  • Reported and fixed across all four affected repos at once: mop, cata, tbc-new and the
    WoWSimsCN-Mop fork. The sink is byte-identical in each, so the patch is the same.
  • sod, tbc-old and wotlk are not affected — they do not have this sink.
  • The wider issue behind it is that allowHTML: true is a global tippy default, which makes
    every tippy({ content }) call site in the tree an HTML sink. This PR fixes the one that is
    reachable from user-controlled data; auditing the rest is worth doing separately.

`ui/index.ts` sets `allowHTML: true` as a global tippy default, and
`makeListItemValidations` builds its tooltip body by interpolating each
validation message into `<li>${v}</li>`. Those messages are not authored
by us: the sim formats user-supplied names straight into them, e.g.
`the APL group-reference and variable validations` — "Group reference '%s' not found" —
and `apl_values_operators.go:668,679` for variable names.

Rotations are shared by link and imported as JSON, so a rotation whose
group is named `<img src=x onerror=...>` runs script in the reader's
browser as soon as the warning tooltip renders.

Escaping after `ActionId.replaceAllInString` loses nothing: that call
substitutes spell *names* as plain text and injects no markup of its own,
so the only markup left in the string is the part we wrote.

Claude-Session: https://claude.ai/code/session_01Cup3PCdDi6MPDRPFDrZoTw
@1337LutZ
1337LutZ merged commit 79c0988 into master Sep 9, 2026
3 checks passed
@1337LutZ
1337LutZ deleted the fix/apl-validation-tooltip-escaping branch September 9, 2026 07:44
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