ソースを参照

another fuzzing find

Blake Mizerany 1 年間 前
コミット
d85fbd0e99

+ 25 - 17
x/build/blob/ref.go

@@ -19,6 +19,15 @@ const (
 	Build
 )
 
+var kindNames = map[PartKind]string{
+	Invalid:   "Invalid",
+	Domain:    "Domain",
+	Namespace: "Namespace",
+	Name:      "Name",
+	Tag:       "Tag",
+	Build:     "Build",
+}
+
 // Ref is an opaque reference to a blob.
 //
 // It is comparable and can be used as a map key.
@@ -219,12 +228,11 @@ func Parts(s string) iter.Seq2[PartKind, string] {
 			return
 		}
 
-		yieldValid := func(kind PartKind, value string) bool {
-			if !isValidPart(value) {
-				yield(Invalid, "")
-				return false
+		yieldValid := func(kind PartKind, part string) bool {
+			if !isValidPart(part) {
+				return yield(Invalid, "")
 			}
-			return yield(kind, value)
+			return yield(kind, part)
 		}
 
 		state, j := Build, len(s)
@@ -238,16 +246,18 @@ func Parts(s string) iter.Seq2[PartKind, string] {
 					}
 					state, j = Tag, i
 				default:
+					yield(Invalid, "")
 					return
 				}
 			case ':':
 				switch state {
 				case Build, Tag:
-					if yieldValid(Tag, s[i+1:j]) {
-						state, j = Tag, i
+					if !yieldValid(Tag, s[i+1:j]) {
+						return
 					}
 					state, j = Name, i
 				default:
+					yield(Invalid, "")
 					return
 				}
 			case '/':
@@ -262,23 +272,21 @@ func Parts(s string) iter.Seq2[PartKind, string] {
 						return
 					}
 					state, j = Domain, i
-				case Domain:
-					// domain is not allowed to have slashes
+				default:
 					yield(Invalid, "")
 					return
-				default:
+				}
+			default:
+				if !isValidPart(s[i : i+1]) {
+					yield(Invalid, "")
 					return
 				}
 			}
 		}
 
-		// handle the first part based on final state
-		switch state {
-		case Domain:
-			yieldValid(Domain, s[:j])
-		case Namespace:
-			yieldValid(Namespace, s[:j])
-		default:
+		if state <= Namespace {
+			yieldValid(state, s[:j])
+		} else {
 			yieldValid(Name, s[:j])
 		}
 	}

+ 10 - 3
x/build/blob/ref_test.go

@@ -21,12 +21,19 @@ var testRefs = map[string]Ref{
 	"mistral:7b+q4_0":     {name: "mistral", tag: "7b", build: "Q4_0"},
 	"llama2":              {name: "llama2"},
 
-	// invalid
+	// invalid (includes fuzzing trophies)
 	"mistral:7b+Q4_0:latest": {},
 	"mi tral":                {},
 	"x/y/z/foo":              {},
 	"/0":                     {},
+	"0 /0":                   {},
+	"0 /":                    {},
 	"0/":                     {},
+	":":                      {},
+	":/0":                    {},
+	"+0/00000":               {},
+	"0+.\xf2\x80\xf6\x9d00000\xe5\x99\xe6\xd900\xd90\xa60\x91\xdc0\xff\xbf\x99\xe800\xb9\xdc\xd6\xc300\x970\xfb\xfd0\xe0\x8a\xe1\xad\xd40\x9700\xa80\x980\xdd0000\xb00\x91000\xfe0\x89\x9b\x90\x93\x9f0\xe60\xf7\x84\xb0\x87\xa5\xff0\xa000\x9a\x85\xf6\x85\xfe\xa9\xf9\xe9\xde00\xf4\xe0\x8f\x81\xad\xde00\xd700\xaa\xe000000\xb1\xee0\x91": {},
+	"0//0": {},
 }
 
 func TestRefParts(t *testing.T) {
@@ -47,7 +54,7 @@ func TestParseRef(t *testing.T) {
 
 			// test round-trip
 			if ParseRef(got.String()) != got {
-				t.Errorf("String() = %q; want %q", got.String(), s)
+				t.Errorf("String() = %s; want %s", got.String(), s)
 			}
 		})
 	}
@@ -125,7 +132,7 @@ func FuzzParseRef(f *testing.F) {
 
 		r1 := ParseRef(r0.String())
 		if r0 != r1 {
-			t.Errorf("round-trip mismatch: %q != %q", r0, r1)
+			t.Errorf("round-trip mismatch: %+v != %+v", r0, r1)
 		}
 	})
 }

+ 2 - 0
x/build/blob/testdata/fuzz/FuzzParseRef/27fd759314f0e6d6

@@ -0,0 +1,2 @@
+go test fuzz v1
+string("0//0")

+ 2 - 0
x/build/blob/testdata/fuzz/FuzzParseRef/71f1fdff711b6dab

@@ -0,0 +1,2 @@
+go test fuzz v1
+string("+0/00000")

+ 2 - 0
x/build/blob/testdata/fuzz/FuzzParseRef/82c2975c430ac608

@@ -0,0 +1,2 @@
+go test fuzz v1
+string(":")

+ 2 - 0
x/build/blob/testdata/fuzz/FuzzParseRef/b51b1c875e61a948

@@ -0,0 +1,2 @@
+go test fuzz v1
+string("0+.\xf2\x80\xf6\x9d00000\xe5\x99\xe6\xd900\xd90\xa60\x91\xdc0\xff\xbf\x99\xe800\xb9\xdc\xd6\xc300\x970\xfb\xfd0\xe0\x8a\xe1\xad\xd40\x9700\xa80\x980\xdd0000\xb00\x91000\xfe0\x89\x9b\x90\x93\x9f0\xe60\xf7\x84\xb0\x87\xa5\xff0\xa000\x9a\x85\xf6\x85\xfe\xa9\xf9\xe9\xde00\xf4\xe0\x8f\x81\xad\xde00\xd700\xaa\xe000000\xb1\xee0\x91")