mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-10 07:05:02 +03:00
fix(link): decode share link remarks once (#6977)
url.Parse already unescapes the fragment, and decodeHash unescaped it again, so a + in a vless, trojan, hysteria2 or wireguard remark became a space and an escaped % was decoded twice. These parsers now pass the escaped fragment, decoding it once like the shadowsocks parser and the frontend.
This commit is contained in:
@@ -387,7 +387,7 @@ func parseVless(link string) (*ParseResult, error) {
|
|||||||
|
|
||||||
ob := Outbound{
|
ob := Outbound{
|
||||||
"protocol": "vless",
|
"protocol": "vless",
|
||||||
"tag": decodeHash(u.Fragment),
|
"tag": decodeHash(u.EscapedFragment()),
|
||||||
"settings": map[string]any{
|
"settings": map[string]any{
|
||||||
"address": host,
|
"address": host,
|
||||||
"port": port,
|
"port": port,
|
||||||
@@ -429,7 +429,7 @@ func parseTrojan(link string) (*ParseResult, error) {
|
|||||||
|
|
||||||
ob := Outbound{
|
ob := Outbound{
|
||||||
"protocol": "trojan",
|
"protocol": "trojan",
|
||||||
"tag": decodeHash(u.Fragment),
|
"tag": decodeHash(u.EscapedFragment()),
|
||||||
"settings": map[string]any{
|
"settings": map[string]any{
|
||||||
"servers": []any{
|
"servers": []any{
|
||||||
map[string]any{"address": host, "port": port, "password": pw},
|
map[string]any{"address": host, "port": port, "password": pw},
|
||||||
@@ -634,7 +634,7 @@ func parseHysteria2(link string) (*ParseResult, error) {
|
|||||||
|
|
||||||
ob := Outbound{
|
ob := Outbound{
|
||||||
"protocol": "hysteria",
|
"protocol": "hysteria",
|
||||||
"tag": decodeHash(u.Fragment),
|
"tag": decodeHash(u.EscapedFragment()),
|
||||||
"settings": map[string]any{"address": host, "port": port, "version": 2},
|
"settings": map[string]any{"address": host, "port": port, "version": 2},
|
||||||
"streamSettings": stream,
|
"streamSettings": stream,
|
||||||
}
|
}
|
||||||
@@ -712,7 +712,7 @@ func parseWireguard(link string) (*ParseResult, error) {
|
|||||||
|
|
||||||
ob := Outbound{
|
ob := Outbound{
|
||||||
"protocol": "wireguard",
|
"protocol": "wireguard",
|
||||||
"tag": decodeHash(u.Fragment),
|
"tag": decodeHash(u.EscapedFragment()),
|
||||||
"settings": settings,
|
"settings": settings,
|
||||||
}
|
}
|
||||||
return &ParseResult{Outbound: ob, Identity: identity}, nil
|
return &ParseResult{Outbound: ob, Identity: identity}, nil
|
||||||
|
|||||||
@@ -430,3 +430,34 @@ func TestParse_VmessFinalMask(t *testing.T) {
|
|||||||
t.Fatalf("finalmask.udp = %#v, want %#v", udp, want)
|
t.Fatalf("finalmask.udp = %#v, want %#v", udp, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParse_RemarkDecodedOnce(t *testing.T) {
|
||||||
|
// Remarks as the subscription server writes them (encodeURIComponent).
|
||||||
|
cases := []struct {
|
||||||
|
fragment string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{"VIP%2B", "VIP+"},
|
||||||
|
{"US%2BEU%201", "US+EU 1"},
|
||||||
|
{"a%2520b", "a%20b"},
|
||||||
|
{"%D0%A2%D0%B5%D1%81%D1%82", "Тест"},
|
||||||
|
}
|
||||||
|
prefixes := []string{
|
||||||
|
"vless://uuid@1.2.3.4:443?type=tcp#",
|
||||||
|
"trojan://pw@1.2.3.4:443#",
|
||||||
|
"hysteria2://auth@1.2.3.4:443#",
|
||||||
|
"wireguard://key@1.2.3.4:51820?publickey=pub#",
|
||||||
|
"ss://YWVzLTI1Ni1nY206cHc@1.2.3.4:8388#",
|
||||||
|
}
|
||||||
|
for _, p := range prefixes {
|
||||||
|
for _, c := range cases {
|
||||||
|
res, err := ParseLink(p + c.fragment)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("parse %s%s: %v", p, c.fragment, err)
|
||||||
|
}
|
||||||
|
if res.Outbound["tag"] != c.want {
|
||||||
|
t.Errorf("%s%s: tag = %q, want %q", p, c.fragment, res.Outbound["tag"], c.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user