From 21911e84e00fbffd5f1962920202d362c32d864b Mon Sep 17 00:00:00 2001 From: irrlicht Date: Tue, 16 Jun 2026 08:21:14 +0200 Subject: [PATCH] auth: Unicode-Usernames in sanitizeUsername erhalten MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit reNonWord nutzte \w, das in Go-RE2 ASCII-only ist und Nicht-ASCII-Buchstaben (z. B. den migrierten Namen "佳紫达尔") restlos entfernte. Da sanitizeUsername auch auf die Login-Eingabe angewandt wird, konnten sich solche -- aus der Python-Prod-DB migrierten -- Konten gar nicht mehr anmelden und nicht umbenannt werden. Ersetzt durch \p{L}\p{N} (Buchstaben/Ziffern aller Schriften). Zusätzlich Längenkürzung auf Runen- statt Byte-Basis, damit der 32er-Schnitt nicht mitten in eine Multibyte-Rune fällt und kaputtes UTF-8 erzeugt. Co-Authored-By: Claude Opus 4.8 --- auth.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/auth.go b/auth.go index c981a0a..0198883 100644 --- a/auth.go +++ b/auth.go @@ -22,7 +22,10 @@ type Session struct { } var ( - reNonWord = regexp.MustCompile(`[^._\w\s-]`) + // \p{L}\p{N} statt \w: Go-RE2-\w ist ASCII-only und würde Unicode-Namen + // (z. B. "佳紫达尔") komplett entfernen -> Login/Rename unmöglich. \p{L}\p{N} + // lässt Buchstaben und Ziffern aller Schriften zu. + reNonWord = regexp.MustCompile(`[^._\p{L}\p{N}\s-]`) reSpace = regexp.MustCompile(`\s+`) ) @@ -189,8 +192,10 @@ func handleHeaderbar(w http.ResponseWriter, r *http.Request) { func sanitizeUsername(u string) string { u = strings.TrimSpace(u) - if len(u) > 32 { - u = u[:32] + // Auf 32 Zeichen (Runen) kürzen, nicht 32 Bytes -- sonst kann der Schnitt + // mitten in eine Multibyte-Rune fallen und kaputtes UTF-8 erzeugen. + if r := []rune(u); len(r) > 32 { + u = string(r[:32]) } u = reNonWord.ReplaceAllString(u, "") u = reSpace.ReplaceAllString(u, "_")