fix(xray): refuse geodata settings xray-core 26.10.29 refuses at startup

xray-core 26.10.29 (#7267) checks a scheduled geodata section when the
core starts: at most 100 assets, every file a .dat, a cron it can parse
and an @every interval of at least a minute. A refusal there stops the
core and every inbound with it, and the panel's own file-name pattern
still let any extension through.

The geodata editor now requires a .dat file name, and the template save
path applies the same checks the core does. The invalid-file hint names
the .dat requirement in all 14 locales.
This commit is contained in:
MHSanaei
2026-11-01 14:55:41 +01:00
parent e789583b63
commit 7982794291
18 changed files with 121 additions and 16 deletions
+39
View File
@@ -3,6 +3,7 @@ package service
import (
"encoding/json"
"errors"
"strconv"
"strings"
"testing"
@@ -289,6 +290,44 @@ func TestCheckXrayConfig_RefusesLuaScriptsTheCoreRefuses(t *testing.T) {
}
}
// xray-core 26.10.29 (#7267) refuses these geodata settings when the core starts, stopping every inbound.
func TestCheckXrayConfig_RefusesGeodataTheCoreRefuses(t *testing.T) {
const outbounds = `"outbounds":[{"protocol":"freedom","tag":"direct"}]`
geodata := func(cron string, files ...string) string {
assets := make([]string, len(files))
for i, f := range files {
assets[i] = `{"url":"https://example.com/` + f + `","file":"` + f + `"}`
}
return `{"geodata":{"cron":"` + cron + `","assets":[` + strings.Join(assets, ",") + `]},` + outbounds + `}`
}
tooMany := make([]string, 101)
for i := range tooMany {
tooMany[i] = "geo" + strconv.Itoa(i) + ".dat"
}
tests := []struct{ name, template, want string }{
{"file that is not .dat", geodata("0 4 * * *", "custom.mmdb"), "file extension must be .dat"},
{"more than 100 assets", geodata("0 4 * * *", tooMany...), "at most 100 assets"},
{"cron the core cannot parse", geodata("every day", "custom.dat"), "invalid geodata cron"},
{"interval under a minute", geodata("@every 30s", "custom.dat"), "at least 1 minute"},
{"upper-case extension on a daily cron", geodata("0 4 * * *", "Custom.DAT"), ""},
{"no cron leaves the assets unscheduled", geodata("", "custom.mmdb"), ""},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
err := (&XraySettingService{}).CheckXrayConfig(tc.template)
if tc.want == "" {
if err != nil {
t.Fatalf("CheckXrayConfig = %v, want the geodata the core accepts kept", err)
}
return
}
if err == nil || !strings.Contains(err.Error(), tc.want) {
t.Fatalf("CheckXrayConfig = %v, want one containing %q", err, tc.want)
}
})
}
}
// A template saved under 26.10.10 can carry those scripts; the build drops them so the core still
// starts, and the vendored loader accepts the routing and dns sections it then emits.
func TestGetXrayConfig_DropsLuaScriptsTheCoreRefuses(t *testing.T) {