mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-02 19:25:05 +03:00
fix(sub): escape a VLESS id the way the panel's own links do
Subscription links escaped the VLESS id with url.QueryEscape, while the panel builds its own link and QR through the browser's URL parser, which escapes userinfo with the WHATWG userinfo set. A non-UUID id such as team+1 was therefore served as team%2B1 by the subscription and as team+1 in the QR, and a client that does not percent-decode userinfo authenticated with a different id depending on where it came from. The id is now escaped with exactly that set, which still keeps a line break or an "@" from splitting the link.
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -231,3 +232,25 @@ func TestGenVlessLinkEscapesID(t *testing.T) {
|
||||
t.Fatalf("vless id not escaped: %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
// The panel builds its own link and QR through the browser's URL parser, which escapes
|
||||
// userinfo with the WHATWG userinfo set; a subscription escaping more serves another id.
|
||||
func TestGenVlessLinkEscapesIDLikeThePanel(t *testing.T) {
|
||||
for id, want := range map[string]string{
|
||||
"team+1": "team+1",
|
||||
"a=b": "a%3Db",
|
||||
"x:y;z": "x%3Ay%3Bz",
|
||||
"ok!$,'()*~": "ok!$,'()*~",
|
||||
"é": "%C3%A9",
|
||||
} {
|
||||
in := &model.Inbound{
|
||||
Listen: "203.0.113.5", Port: 443, Protocol: model.VLESS, Remark: "n",
|
||||
Settings: `{"clients":[{"id":` + strconv.Quote(id) + `,"email":"user"}],"decryption":"none"}`,
|
||||
StreamSettings: `{"network":"tcp","security":"none"}`,
|
||||
}
|
||||
got := NewSubService("").genVlessLink(in, "user")
|
||||
if !strings.HasPrefix(got, "vless://"+want+"@203.0.113.5:443?") {
|
||||
t.Errorf("id %q: link %q, want userinfo %q", id, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user