From 287e3616ba1e583ecf3699f965e658865b0ae12e Mon Sep 17 00:00:00 2001 From: Erik Dubbelboer Date: Sat, 20 Jan 2024 05:10:41 +0100 Subject: Make Fuzz tests deterministic From the Go docs: - Fuzz targets should be fast and deterministic so the fuzzing engine can work efficiently, and new failures and code coverage can be easily reproduced. - Since the fuzz target is invoked in parallel across multiple workers and in nondeterministic order, the state of a fuzz target should not persist past the end of each call, and the behavior of a fuzz target should not depend on global state. --- fuzz_test.go | 53 +++++++++++++++++++++-------------------------------- 1 file changed, 21 insertions(+), 32 deletions(-) diff --git a/fuzz_test.go b/fuzz_test.go index 827e776..f797ee4 100644 --- a/fuzz_test.go +++ b/fuzz_test.go @@ -7,17 +7,13 @@ import ( ) func FuzzCookieParse(f *testing.F) { - inputs := []string{ - `xxx=yyy`, - `xxx=yyy; expires=Tue, 10 Nov 2009 23:00:00 GMT; domain=foobar.com; path=/a/b`, - " \n\t\"", - } - for _, input := range inputs { - f.Add([]byte(input)) - } - c := AcquireCookie() - defer ReleaseCookie(c) + f.Add([]byte(`xxx=yyy`)) + f.Add([]byte(`xxx=yyy; expires=Tue, 10 Nov 2009 23:00:00 GMT; domain=foobar.com; path=/a/b`)) + f.Add([]byte(" \n\t\"")) + f.Fuzz(func(t *testing.T, cookie []byte) { + var c Cookie + _ = c.ParseBytes(cookie) w := bytes.Buffer{} @@ -28,15 +24,11 @@ func FuzzCookieParse(f *testing.F) { } func FuzzVisitHeaderParams(f *testing.F) { - inputs := []string{ - `application/json; v=1; foo=bar; q=0.938; param=param; param="big fox"; q=0.43`, - `*/*`, - `\\`, - `text/plain; foo="\\\"\'\\''\'"`, - } - for _, input := range inputs { - f.Add([]byte(input)) - } + f.Add([]byte(`application/json; v=1; foo=bar; q=0.938; param=param; param="big fox"; q=0.43`)) + f.Add([]byte(`*/*`)) + f.Add([]byte(`\\`)) + f.Add([]byte(`text/plain; foo="\\\"\'\\''\'"`)) + f.Fuzz(func(t *testing.T, header []byte) { VisitHeaderParams(header, func(key, value []byte) bool { if len(key) == 0 { @@ -48,16 +40,15 @@ func FuzzVisitHeaderParams(f *testing.F) { } func FuzzResponseReadLimitBody(f *testing.F) { - res := AcquireResponse() - defer ReleaseResponse(res) - - f.Add([]byte("HTTP/1.1 200 OK\r\nContent-Type: aa\r\nContent-Length: 10\r\n\r\n9876543210"), 1024*1024) + f.Add([]byte("HTTP/1.1 200 OK\r\nContent-Type: aa\r\nContent-Length: 10\r\n\r\n9876543210"), 1024) f.Fuzz(func(t *testing.T, body []byte, max int) { - if max > 10*1024*1024 { // Skip limits higher than 10MB. + if max > 1024*1024 { // Skip limits higher than 1MB. return } + var res Response + _ = res.ReadLimitBody(bufio.NewReader(bytes.NewReader(body)), max) w := bytes.Buffer{} _, _ = res.WriteTo(&w) @@ -65,16 +56,15 @@ func FuzzResponseReadLimitBody(f *testing.F) { } func FuzzRequestReadLimitBody(f *testing.F) { - req := AcquireRequest() - defer ReleaseRequest(req) - - f.Add([]byte("POST /a HTTP/1.1\r\nHost: a.com\r\nTransfer-Encoding: chunked\r\nContent-Type: aa\r\n\r\n6\r\nfoobar\r\n3\r\nbaz\r\n0\r\nfoobar\r\n\r\n"), 1024*1024) + f.Add([]byte("POST /a HTTP/1.1\r\nHost: a.com\r\nTransfer-Encoding: chunked\r\nContent-Type: aa\r\n\r\n6\r\nfoobar\r\n3\r\nbaz\r\n0\r\nfoobar\r\n\r\n"), 1024) f.Fuzz(func(t *testing.T, body []byte, max int) { - if max > 10*1024*1024 { // Skip limits higher than 10MB. + if max > 1024*1024 { // Skip limits higher than 1MB. return } + var req Request + _ = req.ReadLimitBody(bufio.NewReader(bytes.NewReader(body)), max) w := bytes.Buffer{} _, _ = req.WriteTo(&w) @@ -82,15 +72,14 @@ func FuzzRequestReadLimitBody(f *testing.F) { } func FuzzURIUpdateBytes(f *testing.F) { - u := AcquireURI() - defer ReleaseURI(u) - f.Add([]byte(`http://foobar.com/aaa/bb?cc`)) f.Add([]byte(`//foobar.com/aaa/bb?cc`)) f.Add([]byte(`/aaa/bb?cc`)) f.Add([]byte(`xx?yy=abc`)) f.Fuzz(func(t *testing.T, uri []byte) { + var u URI + u.UpdateBytes(uri) w := bytes.Buffer{} -- cgit v1.2.3