From f7ffe8981313c97e127ff7861930b18b45a8d65d Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Mon, 15 Jun 2026 19:16:57 +0200 Subject: [PATCH] fix(outbound): preserve non-ASCII characters in imported subscription tags (#5354) SlugRemark stripped every non-ASCII character, so tags generated from remarks like Cyrillic names collapsed to just their digits, making imported outbounds hard to identify. Keep Unicode letters and digits in the slug regex while still collapsing punctuation into dashes. --- internal/util/link/outbound.go | 6 ++++-- internal/util/link/outbound_test.go | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/internal/util/link/outbound.go b/internal/util/link/outbound.go index cfcf18b82..8ba193396 100644 --- a/internal/util/link/outbound.go +++ b/internal/util/link/outbound.go @@ -781,8 +781,10 @@ func base64DecodeFlexible(s string) (string, error) { return "", fmt.Errorf("base64 decode failed") } -// SlugRemark turns a free-form remark into a conservative DNS-ish tag segment. -var slugRe = regexp.MustCompile(`[^a-z0-9]+`) +// SlugRemark turns a free-form remark into a tag segment, keeping Unicode +// letters and digits (so non-ASCII remarks like Cyrillic stay readable) and +// replacing every other run of characters with a single dash. +var slugRe = regexp.MustCompile(`[^\p{L}\p{N}]+`) func SlugRemark(remark string) string { s := strings.ToLower(strings.TrimSpace(remark)) diff --git a/internal/util/link/outbound_test.go b/internal/util/link/outbound_test.go index 1dbadaf00..43d2a6079 100644 --- a/internal/util/link/outbound_test.go +++ b/internal/util/link/outbound_test.go @@ -59,4 +59,11 @@ func TestSlugAndSuggest(t *testing.T) { if tag != "hk-sg-01" { t.Errorf("suggest tag got %q", tag) } + // Non-ASCII letters/digits are preserved rather than stripped. + if got := SlugRemark("Москва 🇷🇺 01"); got != "москва-01" { + t.Errorf("unicode slug got %q", got) + } + if got := SuggestTag("ru-", "Сервер 2", 0); got != "ru-сервер-2" { + t.Errorf("unicode suggest tag got %q", got) + } }