auth: Unicode-Usernames in sanitizeUsername erhalten

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 <noreply@anthropic.com>
This commit is contained in:
2026-06-16 08:21:14 +02:00
parent 0089bc5909
commit 21911e84e0
+8 -3
View File
@@ -22,7 +22,10 @@ type Session struct {
} }
var ( 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+`) reSpace = regexp.MustCompile(`\s+`)
) )
@@ -189,8 +192,10 @@ func handleHeaderbar(w http.ResponseWriter, r *http.Request) {
func sanitizeUsername(u string) string { func sanitizeUsername(u string) string {
u = strings.TrimSpace(u) u = strings.TrimSpace(u)
if len(u) > 32 { // Auf 32 Zeichen (Runen) kürzen, nicht 32 Bytes -- sonst kann der Schnitt
u = u[:32] // 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 = reNonWord.ReplaceAllString(u, "")
u = reSpace.ReplaceAllString(u, "_") u = reSpace.ReplaceAllString(u, "_")