Bläddra i källkod

daemon/config: use strings.Cut(), fix panic in BuilderGCFilter

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn 2 år sedan
förälder
incheckning
b529870558
3 ändrade filer med 23 tillägg och 10 borttagningar
  1. 4 5
      daemon/config/builder.go
  2. 14 0
      daemon/config/builder_test.go
  3. 5 5
      daemon/config/config.go

+ 4 - 5
daemon/config/builder.go

@@ -2,7 +2,6 @@ package config
 
 import (
 	"encoding/json"
-	"fmt"
 	"sort"
 	"strings"
 
@@ -28,7 +27,7 @@ func (x *BuilderGCFilter) MarshalJSON() ([]byte, error) {
 	for _, k := range keys {
 		values := f.Get(k)
 		for _, v := range values {
-			arr = append(arr, fmt.Sprintf("%s=%s", k, v))
+			arr = append(arr, k+"="+v)
 		}
 	}
 	return json.Marshal(arr)
@@ -45,9 +44,9 @@ func (x *BuilderGCFilter) UnmarshalJSON(data []byte) error {
 		return err
 	}
 	for _, s := range arr {
-		fields := strings.SplitN(s, "=", 2)
-		name := strings.ToLower(strings.TrimSpace(fields[0]))
-		value := strings.TrimSpace(fields[1])
+		name, value, _ := strings.Cut(s, "=")
+		name = strings.ToLower(strings.TrimSpace(name))
+		value = strings.TrimSpace(value)
 		f.Add(name, value)
 	}
 	*x = BuilderGCFilter(f)

+ 14 - 0
daemon/config/builder_test.go

@@ -1,6 +1,7 @@
 package config
 
 import (
+	"encoding/json"
 	"testing"
 
 	"github.com/docker/docker/api/types/filters"
@@ -42,3 +43,16 @@ func TestBuilderGC(t *testing.T) {
 	assert.Assert(t, filters.Args(cfg.Builder.GC.Policy[0].Filter).UniqueExactMatch("unused-for", "2200h"))
 	assert.Assert(t, filters.Args(cfg.Builder.GC.Policy[1].Filter).UniqueExactMatch("unused-for", "3300h"))
 }
+
+// TestBuilderGCFilterUnmarshal is a regression test for https://github.com/moby/moby/issues/44361,
+// where and incorrectly formatted gc filter option ("unused-for2200h",
+// missing a "=" separator). resulted in a panic during unmarshal.
+func TestBuilderGCFilterUnmarshal(t *testing.T) {
+	var cfg BuilderGCConfig
+	err := json.Unmarshal([]byte(`{"poliCy": [{"keepStorage": "10GB", "filter": ["unused-for2200h"]}]}`), &cfg)
+	assert.Check(t, err)
+	expectedPolicy := []BuilderGCRule{{
+		KeepStorage: "10GB", Filter: BuilderGCFilter(filters.NewArgs(filters.Arg("unused-for2200h", ""))),
+	}}
+	assert.DeepEqual(t, cfg.Policy, expectedPolicy, cmp.AllowUnexported(BuilderGCFilter{}))
+}

+ 5 - 5
daemon/config/config.go

@@ -313,13 +313,13 @@ func New() (*Config, error) {
 func GetConflictFreeLabels(labels []string) ([]string, error) {
 	labelMap := map[string]string{}
 	for _, label := range labels {
-		stringSlice := strings.SplitN(label, "=", 2)
-		if len(stringSlice) > 1 {
+		key, val, ok := strings.Cut(label, "=")
+		if ok {
 			// If there is a conflict we will return an error
-			if v, ok := labelMap[stringSlice[0]]; ok && v != stringSlice[1] {
-				return nil, errors.Errorf("conflict labels for %s=%s and %s=%s", stringSlice[0], stringSlice[1], stringSlice[0], v)
+			if v, ok := labelMap[key]; ok && v != val {
+				return nil, errors.Errorf("conflict labels for %s=%s and %s=%s", key, val, key, v)
 			}
-			labelMap[stringSlice[0]] = stringSlice[1]
+			labelMap[key] = val
 		}
 	}