Skip to content

fix(export): escape line terminators in Tailwind v4 CSS string values#122

Open
rmyndharis wants to merge 1 commit into
google-labs-code:mainfrom
rmyndharis:fix/v4-css-escape-control-chars
Open

fix(export): escape line terminators in Tailwind v4 CSS string values#122
rmyndharis wants to merge 1 commit into
google-labs-code:mainfrom
rmyndharis:fix/v4-css-escape-control-chars

Conversation

@rmyndharis

Copy link
Copy Markdown

Summary

The Tailwind v4 exporter wraps font-family values with cssStringLiteral, which escaped only \ and ". A value containing a raw newline / carriage return / form feed — valid via a YAML double-quoted or block scalar in a DESIGN.md — was emitted verbatim inside the @theme CSS string literal. Raw line terminators are illegal inside a CSS string and can break the value out of the quoted token, producing malformed CSS.

This complements the existing token-name validation (which already rejects non-identifier names): names are validated, and string values are now fully escaped.

Fix

Escape \n, \r, and \f as CSS hex escapes (e.g. \a ) in cssStringLiteral, alongside the existing \/" escaping.

Testing

  • bun test: 283 pass, 1 skip, 0 fail (added a test: a font-family containing a newline emits "Evil\a Family" with no raw newline)
  • bun run lint (tsc --noEmit): clean
  • Existing quote/backslash escaping test unchanged and passing

cssStringLiteral escaped only backslash and double-quote. A font-family value
containing a raw newline, carriage return, or form feed (legal via a YAML
quoted or block scalar) was emitted verbatim inside the CSS string literal,
where raw line terminators are illegal and can break the value out of the
@theme token. Emit them as CSS hex escapes (e.g. `\a `).

@rajpratham1 rajpratham1 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a well-scoped bug fix that improves the correctness of the generated Tailwind v4 CSS. Escaping line terminators (\n, \r, and \f) as CSS hex escapes prevents invalid CSS string literals while preserving the intended value. The accompanying regression test clearly covers the reported edge case and verifies that raw newlines no longer appear in the emitted output.

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.

2 participants