diff --git a/pkg/kubelet/cm/cpuset/cpuset.go b/pkg/kubelet/cm/cpuset/cpuset.go index de72ba25756..24330e5a9e3 100644 --- a/pkg/kubelet/cm/cpuset/cpuset.go +++ b/pkg/kubelet/cm/cpuset/cpuset.go @@ -301,7 +301,7 @@ func Parse(s string) (CPUSet, error) { ranges := strings.Split(s, ",") for _, r := range ranges { - boundaries := strings.Split(r, "-") + boundaries := strings.SplitN(r, "-", 2) if len(boundaries) == 1 { // Handle ranges that consist of only one element like "34". elem, err := strconv.Atoi(boundaries[0]) @@ -319,6 +319,11 @@ func Parse(s string) (CPUSet, error) { if err != nil { return NewCPUSet(), err } + if start > end { + return NewCPUSet(), fmt.Errorf("invalid range %q (%d >= %d)", r, start, end) + } + // start == end is acceptable (1-1 -> 1) + // Add all elements to the result. // e.g. "0-5", "46-48" => [0, 1, 2, 3, 4, 5, 46, 47, 48]. for e := start; e <= end; e++ { diff --git a/pkg/kubelet/cm/cpuset/cpuset_test.go b/pkg/kubelet/cm/cpuset/cpuset_test.go index c77ab8b7543..d79748df506 100644 --- a/pkg/kubelet/cm/cpuset/cpuset_test.go +++ b/pkg/kubelet/cm/cpuset/cpuset_test.go @@ -323,7 +323,7 @@ func TestCPUSetString(t *testing.T) { } func TestParse(t *testing.T) { - testCases := []struct { + positiveTestCases := []struct { cpusetString string expected CPUSet }{ @@ -332,9 +332,12 @@ func TestParse(t *testing.T) { {"1,2,3,4,5", NewCPUSet(1, 2, 3, 4, 5)}, {"1-5", NewCPUSet(1, 2, 3, 4, 5)}, {"1-2,3-5", NewCPUSet(1, 2, 3, 4, 5)}, + {"5,4,3,2,1", NewCPUSet(1, 2, 3, 4, 5)}, // Range ordering + {"3-6,1-5", NewCPUSet(1, 2, 3, 4, 5, 6)}, // Overlapping ranges + {"3-3,5-5", NewCPUSet(3, 5)}, // Very short ranges } - for _, c := range testCases { + for _, c := range positiveTestCases { result, err := Parse(c.cpusetString) if err != nil { t.Fatalf("expected error not to have occurred: %v", err) @@ -343,4 +346,20 @@ func TestParse(t *testing.T) { t.Fatalf("expected string \"%s\" to parse as [%v] (got [%v])", c.cpusetString, c.expected, result) } } + + negativeTestCases := []string{ + // Non-numeric entries + "nonnumeric", "non-numeric", "no,numbers", "0-a", "a-0", "0,a", "a,0", "1-2,a,3-5", + // Incomplete sequences + "0,", "0,,", ",3", ",,3", "0,,3", + // Incomplete ranges and/or negative numbers + "-1", "1-", "1,2-,3", "1,-2,3", "-1--2", "--1", "1--", + // Reversed ranges + "3-0", "0--3"} + for _, c := range negativeTestCases { + result, err := Parse(c) + if err == nil { + t.Fatalf("expected parse failure of \"%s\", but it succeeded as \"%s\"", c, result.String()) + } + } }