diff --git a/opts/opts.go b/opts/opts.go index 0a7706ca71ff..ed1c2b8a92d6 100644 --- a/opts/opts.go +++ b/opts/opts.go @@ -366,6 +366,10 @@ func ParseCPUs(value string) (int64, error) { if !nano.IsInt() { return 0, errors.New("value is too precise") } + // Int64 keeps the low 64 bits of a value that does not fit. + if !nano.Num().IsInt64() { + return 0, errors.New("value is out of range") + } return nano.Num().Int64(), nil } diff --git a/opts/opts_test.go b/opts/opts_test.go index 598a54a90efa..78425b43417c 100644 --- a/opts/opts_test.go +++ b/opts/opts_test.go @@ -2,6 +2,7 @@ package opts import ( "fmt" + "math" "strings" "testing" @@ -429,6 +430,28 @@ func TestParseCPUsReturnZeroOnInvalidValues(t *testing.T) { assert.Equal(t, z1, resValue) } +func TestParseCPUsRejectsValuesThatDoNotFitInInt64(t *testing.T) { + got, err := ParseCPUs("10000000000") + assert.Error(t, err, "value is out of range") + assert.Equal(t, int64(0), got) + + got, err = ParseCPUs("9223372036.854775808") + assert.Error(t, err, "value is out of range") + assert.Equal(t, int64(0), got) + + got, err = ParseCPUs("-9223372036.854775809") + assert.Error(t, err, "value is out of range") + assert.Equal(t, int64(0), got) + + got, err = ParseCPUs("9223372036.854775807") + assert.NilError(t, err) + assert.Equal(t, int64(math.MaxInt64), got) + + got, err = ParseCPUs("-9223372036.854775808") + assert.NilError(t, err) + assert.Equal(t, int64(math.MinInt64), got) +} + func TestUmaskOpt(t *testing.T) { t.Run("type", func(t *testing.T) { var opt UmaskOpt