fix: sanitizer double-escaped entities ( /&); dot-prefix volumes dir
- chat.SanitizeHTML/SanitizePlain decoded-then-escape text runs, so HTML entities the browser emits (e.g. for the space after a mention chip, or & for a typed "&") no longer render as literal " "/"&". Re-escaping keeps output XSS-safe. Adds regression tests. - Rename ./volumes -> ./.volumes so `go build/vet/test ./...` skip the mongo data dir (700-perm files); Makefile lint now gofmt's tracked files only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -31,10 +31,10 @@ func SanitizeHTML(in string) string {
|
||||
if c != '<' {
|
||||
j := strings.IndexByte(in[i:], '<')
|
||||
if j < 0 {
|
||||
out.WriteString(html.EscapeString(in[i:]))
|
||||
out.WriteString(escapeText(in[i:]))
|
||||
break
|
||||
}
|
||||
out.WriteString(html.EscapeString(in[i : i+j]))
|
||||
out.WriteString(escapeText(in[i : i+j]))
|
||||
i += j
|
||||
continue
|
||||
}
|
||||
@@ -118,6 +118,15 @@ func SanitizeHTML(in string) string {
|
||||
return out.String()
|
||||
}
|
||||
|
||||
// escapeText normalizes a text run from (possibly entity-encoded) input HTML:
|
||||
// decode existing entities, then re-escape. This keeps a single round of
|
||||
// escaping so entities the browser emits — e.g. for spaces around inline
|
||||
// elements, or & for a typed "&" — don't get double-escaped into visible
|
||||
// " "/"&" text. Re-escaping keeps the output XSS-safe.
|
||||
func escapeText(s string) string {
|
||||
return html.EscapeString(html.UnescapeString(s))
|
||||
}
|
||||
|
||||
// splitTag separates the tag name from its raw attribute string.
|
||||
func splitTag(raw string) (string, string) {
|
||||
for i := 0; i < len(raw); i++ {
|
||||
@@ -219,10 +228,10 @@ func SanitizePlain(in string) string {
|
||||
if in[i] != '<' {
|
||||
j := strings.IndexByte(in[i:], '<')
|
||||
if j < 0 {
|
||||
out.WriteString(html.EscapeString(in[i:]))
|
||||
out.WriteString(escapeText(in[i:]))
|
||||
break
|
||||
}
|
||||
out.WriteString(html.EscapeString(in[i : i+j]))
|
||||
out.WriteString(escapeText(in[i : i+j]))
|
||||
i += j
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user