diff --git a/server/commands.go b/server/commands.go index 714e6a3b..008aaf3b 100644 --- a/server/commands.go +++ b/server/commands.go @@ -27,6 +27,7 @@ package server import ( + "bytes" "encoding/json" "fmt" "net" @@ -353,8 +354,21 @@ func getDynamicConfigValues(input []string) (map[dynamicconfig.Key][]dynamicconf key := dynamicconfig.Key(keyVal[0]) // We don't support constraints currently var val dynamicconfig.ConstrainedValue - if err := json.Unmarshal([]byte(keyVal[1]), &val.Value); err != nil { - return nil, fmt.Errorf("invalid JSON value for key %q: %w", key, err) + dec := json.NewDecoder(bytes.NewReader([]byte(keyVal[1]))) + dec.UseNumber() + if err := dec.Decode(&val.Value); err != nil || dec.InputOffset() != int64(len(keyVal[1])) { + return nil, fmt.Errorf("invalid JSON value for key %q", key) + } + if num, ok := val.Value.(json.Number); ok { + if v, err := num.Int64(); err == nil { + // dynamic config only accepts int type, not int32 nor int64 + val.Value = int(v) + } else if v, err := num.Float64(); err == nil { + val.Value = v + } else { + // should not be possible: decoded json.Number must be parsable to int64 or float64 + return nil, fmt.Errorf("invalid JSON value for key %q", key) + } } ret[key] = append(ret[key], val) } diff --git a/server/commands_test.go b/server/commands_test.go index 7af96819..7c57be30 100644 --- a/server/commands_test.go +++ b/server/commands_test.go @@ -59,9 +59,9 @@ func TestGetDynamicConfigValues(t *testing.T) { assertBadVal("foo=bar") assertBadVal("foo=123a") - assertGoodVals(v{"foo": {123.0}}, "foo=123") + assertGoodVals(v{"foo": {123}}, "foo=123") assertGoodVals( - v{"foo": {123.0, []interface{}{"123", false}}, "bar": {"baz"}, "qux": {true}}, + v{"foo": {123, []interface{}{"123", false}}, "bar": {"baz"}, "qux": {true}}, "foo=123", `bar="baz"`, "qux=true", `foo=["123", false]`, ) }