From edb53a4a2988705b108d4b628507def90fbc604b Mon Sep 17 00:00:00 2001 From: Virgil Date: Fri, 3 Apr 2026 17:33:41 +0000 Subject: [PATCH] fix(html): harden variant selector escaping Co-Authored-By: Virgil --- responsive.go | 11 ++++++++++- responsive_test.go | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/responsive.go b/responsive.go index 59aa642..046d092 100644 --- a/responsive.go +++ b/responsive.go @@ -1,6 +1,9 @@ package html -import "strings" +import ( + "strconv" + "strings" +) // responsive.go: Responsive wraps multiple Layout variants for breakpoint-aware rendering. // Example: NewResponsive().Variant("desktop", NewLayout("C").C(Raw("main"))). @@ -36,6 +39,12 @@ func escapeCSSString(s string) string { case '\f': b.WriteString(`\c `) default: + if r < 0x20 || r == 0x7f { + b.WriteByte('\\') + b.WriteString(strings.ToLower(strconv.FormatInt(int64(r), 16))) + b.WriteByte(' ') + continue + } b.WriteRune(r) } } diff --git a/responsive_test.go b/responsive_test.go index 0bdbd50..351ed3b 100644 --- a/responsive_test.go +++ b/responsive_test.go @@ -123,6 +123,7 @@ func TestVariantSelector(t *testing.T) { }{ {name: "plain", variant: "desktop", want: `[data-variant="desktop"]`}, {name: "escaped", variant: `desk"top\` + "\n" + `line`, want: `[data-variant="desk\"top\\\a line"]`}, + {name: "control char", variant: "tab\tname", want: `[data-variant="tab\9 name"]`}, } for _, tt := range tests {