sanitizeCssValue's blanket `;` strip ran on the whole value AFTER url(...)
content was already safely re-wrapped, corrupting legitimate
data:image/png;base64,... URLs pasted into Background Image fields
(the MIME/base64 separator `;` was deleted, breaking the data URI in
exported/published HTML). Scope the `;`/`"` breakout sanitization to the
segments outside url(...) matches only -- the url() branch is already
fully safe via escapeAttr(safeUrl(...)) and must not be re-stripped.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cssPropsToString() joined raw CSSProperties values into a style="..."
attribute with zero escaping, so any component spreading user-controlled
values into inline styles (background-image url(), etc.) could break
out of the attribute or inject a second declaration -- this is what
made BackgroundSection/HeroSimple/CallToAction/Section's bg-image
url() sites (flagged in the A3 brief) safe without needing a per-call-
site fix, since they already route through this helper.
Each string value is now sanitized: url(...) contents are validated
through safeUrl and re-wrapped escaped, stray `;` (the only way to
inject a second live declaration) is stripped, and any raw `"` is
entity-encoded so it can't terminate the attribute early. Legitimate
multi-part values (box-shadow, gradients) that contain none of these
characters pass through byte-identical.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>