From d85fbd0e99fb3df786c5c51ab85dbb4dd939acac Mon Sep 17 00:00:00 2001 From: Blake Mizerany Date: Thu, 4 Apr 2024 00:47:52 -0700 Subject: [PATCH] another fuzzing find --- x/build/blob/ref.go | 42 +++++++++++-------- x/build/blob/ref_test.go | 13 ++++-- .../fuzz/FuzzParseRef/27fd759314f0e6d6 | 2 + .../fuzz/FuzzParseRef/71f1fdff711b6dab | 2 + .../fuzz/FuzzParseRef/82c2975c430ac608 | 2 + .../fuzz/FuzzParseRef/b51b1c875e61a948 | 2 + 6 files changed, 43 insertions(+), 20 deletions(-) create mode 100644 x/build/blob/testdata/fuzz/FuzzParseRef/27fd759314f0e6d6 create mode 100644 x/build/blob/testdata/fuzz/FuzzParseRef/71f1fdff711b6dab create mode 100644 x/build/blob/testdata/fuzz/FuzzParseRef/82c2975c430ac608 create mode 100644 x/build/blob/testdata/fuzz/FuzzParseRef/b51b1c875e61a948 diff --git a/x/build/blob/ref.go b/x/build/blob/ref.go index a925a928..361b44a3 100644 --- a/x/build/blob/ref.go +++ b/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]) } } diff --git a/x/build/blob/ref_test.go b/x/build/blob/ref_test.go index 533f5585..4e7a2fb2 100644 --- a/x/build/blob/ref_test.go +++ b/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) } }) } diff --git a/x/build/blob/testdata/fuzz/FuzzParseRef/27fd759314f0e6d6 b/x/build/blob/testdata/fuzz/FuzzParseRef/27fd759314f0e6d6 new file mode 100644 index 00000000..c5d09a4c --- /dev/null +++ b/x/build/blob/testdata/fuzz/FuzzParseRef/27fd759314f0e6d6 @@ -0,0 +1,2 @@ +go test fuzz v1 +string("0//0") diff --git a/x/build/blob/testdata/fuzz/FuzzParseRef/71f1fdff711b6dab b/x/build/blob/testdata/fuzz/FuzzParseRef/71f1fdff711b6dab new file mode 100644 index 00000000..fa981c52 --- /dev/null +++ b/x/build/blob/testdata/fuzz/FuzzParseRef/71f1fdff711b6dab @@ -0,0 +1,2 @@ +go test fuzz v1 +string("+0/00000") diff --git a/x/build/blob/testdata/fuzz/FuzzParseRef/82c2975c430ac608 b/x/build/blob/testdata/fuzz/FuzzParseRef/82c2975c430ac608 new file mode 100644 index 00000000..0a66beb8 --- /dev/null +++ b/x/build/blob/testdata/fuzz/FuzzParseRef/82c2975c430ac608 @@ -0,0 +1,2 @@ +go test fuzz v1 +string(":") diff --git a/x/build/blob/testdata/fuzz/FuzzParseRef/b51b1c875e61a948 b/x/build/blob/testdata/fuzz/FuzzParseRef/b51b1c875e61a948 new file mode 100644 index 00000000..db07727d --- /dev/null +++ b/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")