mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-05-08 14:13:22 +00:00
Config: Support env XRAY_JSON_STRICT=true (#6053)
https://github.com/XTLS/Xray-core/pull/6053#issuecomment-4363840170 --------- Co-authored-by: RPRX <63339210+RPRX@users.noreply.github.com>
This commit is contained in:
@@ -17,6 +17,7 @@ const (
|
||||
UseFreedomSplice = "xray.buf.splice"
|
||||
UseVmessPadding = "xray.vmess.padding"
|
||||
UseCone = "xray.cone.disabled"
|
||||
UseStrictJSON = "xray.json.strict"
|
||||
|
||||
BufferSize = "xray.ray.buffer.size"
|
||||
BrowserDialerAddress = "xray.browser.dialer"
|
||||
|
||||
@@ -5,12 +5,22 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/common/platform"
|
||||
creflect "github.com/xtls/xray-core/common/reflect"
|
||||
"github.com/xtls/xray-core/core"
|
||||
"github.com/xtls/xray-core/infra/conf"
|
||||
"github.com/xtls/xray-core/main/confloader"
|
||||
)
|
||||
|
||||
// UseStrictJSON, when true, makes JSON config decoders skip the custom
|
||||
// comment-stripping reader and parse input as strict RFC 8259 JSON.
|
||||
//
|
||||
// Enabled by setting the env variable xray.json.strict=true (or its normalized
|
||||
// form XRAY_JSON_STRICT=true). Default false preserves backward-compatible
|
||||
// behavior for human-edited configs that may contain comments or other
|
||||
// JSON5/JSONC syntax.
|
||||
var UseStrictJSON = platform.NewEnvFlag(platform.UseStrictJSON).GetValue(func() string { return "" }) == "true"
|
||||
|
||||
func MergeConfigFromFiles(files []*core.ConfigSource) (string, error) {
|
||||
c, err := mergeConfigs(files)
|
||||
if err != nil {
|
||||
@@ -31,7 +41,11 @@ func mergeConfigs(files []*core.ConfigSource) (*conf.Config, error) {
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to read config: ", file).Base(err)
|
||||
}
|
||||
c, err := ReaderDecoderByFormat[file.Format](r)
|
||||
decoder := ReaderDecoderByFormat[file.Format]
|
||||
if file.Format == "json" && UseStrictJSON {
|
||||
decoder = DecodeJSONConfigStrict
|
||||
}
|
||||
c, err := decoder(r)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to decode config: ", file).Base(err)
|
||||
}
|
||||
|
||||
@@ -42,6 +42,9 @@ func findOffset(b []byte, o int) *offset {
|
||||
|
||||
// DecodeJSONConfig reads from reader and decode the config into *conf.Config
|
||||
// syntax error could be detected.
|
||||
//
|
||||
// Permissive: accepts JSON with Java/Python-style comments via json_reader.Reader.
|
||||
// Used for local files and stdin where the config is human-edited.
|
||||
func DecodeJSONConfig(reader io.Reader) (*conf.Config, error) {
|
||||
jsonConfig := &conf.Config{}
|
||||
|
||||
@@ -69,6 +72,24 @@ func DecodeJSONConfig(reader io.Reader) (*conf.Config, error) {
|
||||
return jsonConfig, nil
|
||||
}
|
||||
|
||||
// DecodeJSONConfigStrict reads standard RFC 8259 JSON without comment-stripping.
|
||||
// Used for remote sources (http/https/http+unix) where the payload is produced by
|
||||
// automated systems and cannot contain JSON5/JSONC extensions. Avoids the
|
||||
// byte-by-byte comment stripper and TeeReader, which are significant overhead on
|
||||
// large configs.
|
||||
func DecodeJSONConfigStrict(reader io.Reader) (*conf.Config, error) {
|
||||
data, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to read config file").Base(err)
|
||||
}
|
||||
jsonConfig := &conf.Config{}
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return nil, errors.New("failed to parse remote JSON config").Base(err)
|
||||
}
|
||||
return jsonConfig, nil
|
||||
}
|
||||
|
||||
|
||||
func LoadJSONConfig(reader io.Reader) (*core.Config, error) {
|
||||
jsonConfig, err := DecodeJSONConfig(reader)
|
||||
if err != nil {
|
||||
|
||||
@@ -41,6 +41,13 @@ func init() {
|
||||
}
|
||||
return cf.Build()
|
||||
case io.Reader:
|
||||
if serial.UseStrictJSON {
|
||||
cfg, err := serial.DecodeJSONConfigStrict(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cfg.Build()
|
||||
}
|
||||
return serial.LoadJSONConfig(v)
|
||||
default:
|
||||
return nil, errors.New("unknown type")
|
||||
|
||||
Reference in New Issue
Block a user