Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GODRIVER-2550 Add fuzzer to bson packages #1077

Merged
merged 23 commits into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
daf51bc
GODRIVER-2550 Add fuzzer to bson packages
prestonvasquez Sep 15, 2022
bb4f333
GODRIVER-2550 update comment
prestonvasquez Sep 15, 2022
00be7df
GODRIVER-2550 add known crashers and new decoder targets
prestonvasquez Sep 15, 2022
58a2afd
GODRIVER-2550 unify the binary
prestonvasquez Sep 15, 2022
839da00
GODRIVER-2550 organizing case types
prestonvasquez Sep 15, 2022
ee9ff08
GODRIVER-2550 update coverage
prestonvasquez Sep 16, 2022
0cfb457
GODRIVER-2550 remove debuggers
prestonvasquez Sep 16, 2022
7337330
GODRIVER-2550 setup EG workflow
prestonvasquez Sep 28, 2022
41efed0
remove mongo orchestration
prestonvasquez Sep 29, 2022
8a0d0e8
remove fuzz tags
prestonvasquez Sep 29, 2022
c4af531
Merge branch 'master' into GODRIVER-2550
prestonvasquez Sep 29, 2022
f2398f3
give fuzz it's own matrix
prestonvasquez Sep 29, 2022
86aae74
add function to seed the bson corpus
prestonvasquez Sep 29, 2022
e4ab0f6
abstract ext json seeding logic
prestonvasquez Sep 29, 2022
c6d97d5
clean up logic
prestonvasquez Sep 29, 2022
55dac80
remove debug tools
prestonvasquez Sep 29, 2022
e210fb1
remove empty lines at the end of EG config
prestonvasquez Sep 29, 2022
4a322c1
remove empty lines at the end of run-fuzz
prestonvasquez Sep 29, 2022
1820a5e
decouple test case fuzz
prestonvasquez Sep 30, 2022
045dc76
rename rbytes to jbytes
prestonvasquez Sep 30, 2022
aec25d1
GODRIVER-2550 fix time (s) to (h) conversion typo
prestonvasquez Oct 3, 2022
0ee3576
GODRIVER-2550 review updates
prestonvasquez Oct 5, 2022
26b3710
GODRIVER-2550 remove cache cleanup, fix spacing typo
prestonvasquez Oct 5, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 31 additions & 3 deletions .evergreen/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ command_type: setup
# Fail builds when pre tasks fail.
pre_error_fails_task: true

# Protect ourself against rogue test case, or curl gone wild, that runs forever
# 12 minutes is the longest we'll ever run
exec_timeout_secs: 3600 # 12 minutes is the longest we'll ever run
# Protect the CI from long or indefinite runtimes.
exec_timeout_secs: 3600

# What to do when evergreen hits the timeout (`post:` tasks are run automatically)
timeout:
Expand Down Expand Up @@ -203,6 +202,16 @@ functions:
permissions: public-read
content_type: ${content_type|application/x-gzip}
display_name: "mongodb-logs.tar.gz"
- command: s3.put
params:
aws_key: ${aws_key}
aws_secret: ${aws_secret}
local_file: ${PROJECT_DIRECTORY}/fuzz.tgz
remote_file: ${UPLOAD_BUCKET}/${build_variant}/${revision}/${version_id}/${build_id}/${task_id}-${execution}-fuzz.tgz
bucket: mciuploads
permissions: public-read
content_type: application/x-gzip
display_name: "fuzz.tgz"

bootstrap-mongohoused:
- command: shell.exec
Expand Down Expand Up @@ -1000,6 +1009,14 @@ functions:
PKG_CONFIG_PATH=$PKG_CONFIG_PATH \
LD_LIBRARY_PATH=$LD_LIBRARY_PATH

run-fuzz-tests:
- command: shell.exec
type: test
params:
working_dir: "src"
script: |
${PREPARE_SHELL}
${PROJECT_DIRECTORY}/.evergreen/run-fuzz.sh
pre:
- func: fetch-source
- func: prepare-resources
Expand Down Expand Up @@ -1979,6 +1996,11 @@ tasks:
EXPECT_ERROR='unable to retrieve GCP credentials' \
./testgcpkms

- name: "test-fuzz"
commands:
- func: bootstrap-mongo-orchestration
- func: run-fuzz-tests

axes:
- id: version
display_name: MongoDB Version
Expand Down Expand Up @@ -2323,6 +2345,12 @@ buildvariants:
tasks:
- name: ".kms-kmip"

- matrix_name: "fuzz-test"
matrix_spec: { version: ["5.0"], os-ssl-40: ["ubuntu1804-64-go-1-18"] }
display_name: "Fuzz ${version} ${os-ssl-40}"
tasks:
- name: "test-fuzz"

- name: testgcpkms-variant
display_name: "GCP KMS"
run_on:
Expand Down
72 changes: 72 additions & 0 deletions .evergreen/run-fuzz.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/bin/bash

set -o errexit # Exit the script with error if any of the commands fail

FUZZTIME=10m

# Change the working directory to the root of the mongo repository directory
cd $PROJECT_DIRECTORY

# Get all go test files that contain a fuzz test.
FILES=$(grep -r --include='**_test.go' --files-with-matches 'func Fuzz' .)

# For each file, run all of the fuzz tests in sequence, each for -fuzztime=FUZZTIME.
for FILE in ${FILES}
do
PARENTDIR="$(dirname -- "$FILE")"

# Clean testing cache.
go clean -testcache
go clean -fuzzcache
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is cleaning the testcache and fuzzcache necessary?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@matthewdale I don't think it's necessary. I will remove these lines, I typically clean them locally to see how code coverage compares between runs but it doesn't seem like something we'd care about in CI. I will remove these lines.


# Get a list of all fuzz tests in the file.
FUNCS=$(grep -o 'func Fuzz[A-Za-z0-9]*' $FILE | cut -d' ' -f2)

# For each fuzz test in the file, run it for FUZZTIME.
for FUNC in ${FUNCS}
do
echo "Fuzzing \"${FUNC}\" in \"${FILE}\""

# Create a set of directories that are already in the subdirectories testdata/fuzz/$fuzzer corpus. This
# set will be used to differentiate between new and old corpus files.
declare -a cset

if [ -d $PARENTDIR/testdata/fuzz/$FUNC ]; then
# Iterate over the files in the corpus directory and add them to the set.
for SEED in $PARENTDIR/testdata/fuzz/$FUNC/*
do
cset+=("$SEED")
done
fi

go test ${PARENTDIR} -run=${FUNC} -fuzz=${FUNC} -fuzztime=${FUZZTIME} || true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we not care about the output of go test (see the || true)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will still pipe the output, but if the go test panics/errors due to a crash (which is good in the case) we don't want the bash script to terminate, rather continue the generated corpus processing.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an indicator that will let us know the fuzz test caused a panic?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, thanks

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@matthewdale Yes, this should still output the results of the test. If I added a panic to the fuzz test and then added checkpoints to the script like this:

echo "before"
go test ${PARENTDIR} -run=${FUNC} -fuzz=${FUNC} -fuzztime=${FUZZTIME} || true
echo "after"

The output would be

Fuzzing "FuzzDecode" in "./bson/fuzz_test.go"
before
fuzz: elapsed: 0s, gathering baseline coverage: 0/460 completed
failure while testing seed corpus entry: FuzzDecode/seed#0
fuzz: elapsed: 0s, gathering baseline coverage: 0/460 completed
--- FAIL: FuzzDecode (0.08s)
    --- FAIL: FuzzDecode (0.00s)
        testing.go:1356: panic: test
            goroutine 60 [running]:
            runtime/debug.Stack()
                /opt/homebrew/Cellar/go/1.19.1/libexec/src/runtime/debug/stack.go:24 +0x104
            testing.tRunner.func1()
                /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1356 +0x258
            panic({0x104d9f300, 0x104e0eac0})
                /opt/homebrew/Cellar/go/1.19.1/libexec/src/runtime/panic.go:884 +0x204
            go.mongodb.org/mongo-driver/bson.FuzzDecode.func1(0x1400013d718?, {0x10476bb28?, 0x0?, 0x0?})
                /Users/preston.vasquez/Developer/mongo-go-driver/bson/fuzz_test.go:19 +0xb8
            reflect.Value.call({0x104da5400?, 0x104e0d9c0?, 0x13?}, {0x104cc889d, 0x4}, {0x140002d46c0, 0x2, 0x2?})
                /opt/homebrew/Cellar/go/1.19.1/libexec/src/reflect/value.go:584 +0x688
            reflect.Value.Call({0x104da5400?, 0x104e0d9c0?, 0x1400008c820?}, {0x140002d46c0?, 0x0?, 0x1400032e978?})
                /opt/homebrew/Cellar/go/1.19.1/libexec/src/reflect/value.go:368 +0x90
            testing.(*F).Fuzz.func1.1(0x1400007eba0?)
                /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/fuzz.go:337 +0x1dc
            testing.tRunner(0x14000221520, 0x140002d8480)
                /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1446 +0x10c
            created by testing.(*F).Fuzz.func1
                /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/fuzz.go:324 +0x4c4


FAIL
exit status 1
FAIL    go.mongodb.org/mongo-driver/bson        0.298s
after


# Check if any new corpus files were generated for the fuzzer. If there are new corpus files, move them
# to $PROJECT_DIRECTORY/fuzz/$FUNC/* so they can be tarred up and uploaded to S3.
if [ -d $PARENTDIR/testdata/fuzz/$FUNC ]; then
# Iterate over the files in the corpus directory and check if they are in the set.
for CORPUS_FILE in $PARENTDIR/testdata/fuzz/$FUNC/*
do
# Check to see if the value for CORPUS_FILE is in cset.
if [[ ! " ${cset[@]} " =~ " ${CORPUS_FILE} " ]]; then
# Create the directory if it doesn't exist.
if [ ! -d $PROJECT_DIRECTORY/fuzz/$FUNC ]; then
mkdir -p $PROJECT_DIRECTORY/fuzz/$FUNC
fi

# Move the file to the directory.
mv $CORPUS_FILE $PROJECT_DIRECTORY/fuzz/$FUNC

echo "Moved $CORPUS_FILE to $PROJECT_DIRECTORY/fuzz/$FUNC"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
echo "Moved $CORPUS_FILE to $PROJECT_DIRECTORY/fuzz/$FUNC"
echo "Moved new $CORPUS_FILE to $PROJECT_DIRECTORY/fuzz/$FUNC"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a log notifying the user that generated data has been moved to the file which will be tarred and put on S3. It will read like

Moved da39a3ee5e6b4b0d3255bfef95601890afd80709 to /fuzz/FuzzDecode

In this case "new" seems redundant.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair, sounds good.

fi
done
fi
done
done

# If the fuzz directory exists, then tar it up in preparation to upload to S3.
if [ -d $PROJECT_DIRECTORY/fuzz ]; then
echo "Tarring up fuzz directory"
tar -czf $PROJECT_DIRECTORY/fuzz.tgz $PROJECT_DIRECTORY/fuzz
fi

112 changes: 98 additions & 14 deletions bson/bson_corpus_spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"math"
"os"
"path"
"strconv"
"strings"
Expand Down Expand Up @@ -60,11 +60,13 @@ type parseErrorTestCase struct {

const dataDir = "../testdata/bson-corpus/"

func findJSONFilesInDir(t *testing.T, dir string) []string {
func findJSONFilesInDir(dir string) ([]string, error) {
files := make([]string, 0)

entries, err := ioutil.ReadDir(dir)
require.NoError(t, err)
entries, err := os.ReadDir(dir)
if err != nil {
return nil, err
}

for _, entry := range entries {
if entry.IsDir() || path.Ext(entry.Name()) != ".json" {
Expand All @@ -74,7 +76,65 @@ func findJSONFilesInDir(t *testing.T, dir string) []string {
files = append(files, entry.Name())
}

return files
return files, nil
}

// seedExtJSON will add the byte representation of the "extJSON" string to the fuzzer's coprus.
func seedExtJSON(f *testing.F, extJSON string, extJSONType string, desc string) {
jbytes, err := jsonToBytes(extJSON, extJSONType, desc)
if err != nil {
f.Fatalf("failed to convert JSON to bytes: %v", err)
}

f.Add(jbytes)
}

// seedTestCase will add the byte representation for each "extJSON" string of each valid test case to the fuzzer's
// corpus.
func seedTestCase(f *testing.F, tcase *testCase) {
for _, vtc := range tcase.Valid {
seedExtJSON(f, vtc.CanonicalExtJSON, "canonical", vtc.Description)

// Seed the relaxed extended JSON.
if vtc.RelaxedExtJSON != nil {
seedExtJSON(f, *vtc.RelaxedExtJSON, "relaxed", vtc.Description)
}

// Seed the degenerate extended JSON.
if vtc.DegenerateExtJSON != nil {
seedExtJSON(f, *vtc.DegenerateExtJSON, "degenerate", vtc.Description)
}

// Seed the converted extended JSON.
if vtc.ConvertedExtJSON != nil {
seedExtJSON(f, *vtc.ConvertedExtJSON, "converted", vtc.Description)
}
}
}

// seedBSONCorpus will unmarshal the data from "testdata/bson-corpus" into a slice of "testCase" structs and then
// marshal the "*_extjson" field of each "validityTestCase" into a slice of bytes to seed the fuzz corpus.
func seedBSONCorpus(f *testing.F) {
fileNames, err := findJSONFilesInDir(dataDir)
if err != nil {
f.Fatalf("failed to find JSON files in directory %q: %v", dataDir, err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
f.Fatalf("failed to find JSON files in directory %q: %v", dataDir, err)
f.Fatalf("failed to find JSON files in directory %q: %v", dataDir, err)

}

for _, fileName := range fileNames {
filePath := path.Join(dataDir, fileName)

file, err := os.Open(filePath)
if err != nil {
f.Fatalf("failed to open file %q: %v", filePath, err)
}

var tcase testCase
if err := json.NewDecoder(file).Decode(&tcase); err != nil {
f.Fatal(err)
}

seedTestCase(f, &tcase)
}
}

func needsEscapedUnicode(bsonType string) bool {
Expand Down Expand Up @@ -196,11 +256,27 @@ func nativeToBSON(t *testing.T, cB []byte, doc D, testDesc, bType, docSrcDesc st
}

// jsonToNative decodes the extended JSON string (ej) into a native Document
func jsonToNative(t *testing.T, ej, ejType, testDesc string) D {
func jsonToNative(ej, ejType, testDesc string) (D, error) {
var doc D
err := UnmarshalExtJSON([]byte(ej), ejType != "relaxed", &doc)
expectNoError(t, err, fmt.Sprintf("%s: decoding %s extended JSON", testDesc, ejType))
return doc
if err := UnmarshalExtJSON([]byte(ej), ejType != "relaxed", &doc); err != nil {
return nil, fmt.Errorf("%s: decoding %s extended JSON: %w", testDesc, ejType, err)
}
return doc, nil
}

// jsonToBytes decodes the extended JSON string (ej) into canonical BSON and then encodes it into a byte slice.
func jsonToBytes(ej, ejType, testDesc string) ([]byte, error) {
native, err := jsonToNative(ej, ejType, testDesc)
if err != nil {
return nil, err
}

b, err := Marshal(native)
if err != nil {
return nil, fmt.Errorf("%s: encoding %s BSON: %w", testDesc, ejType, err)
}

return b, nil
}

// nativeToJSON encodes the native Document (doc) into an extended JSON string
Expand All @@ -217,7 +293,7 @@ func nativeToJSON(t *testing.T, ej string, doc D, testDesc, ejType, ejShortName,

func runTest(t *testing.T, file string) {
filepath := path.Join(dataDir, file)
content, err := ioutil.ReadFile(filepath)
content, err := os.ReadFile(filepath)
require.NoError(t, err)

// Remove ".json" from filename.
Expand Down Expand Up @@ -260,14 +336,16 @@ func runTest(t *testing.T, file string) {
nativeToJSON(t, rEJ, doc, v.Description, "relaxed", "rEJ", "bson_to_native(cB)")

/*** relaxed extended JSON round-trip tests (if exists) ***/
doc = jsonToNative(t, rEJ, "relaxed", v.Description)
doc, err = jsonToNative(rEJ, "relaxed", v.Description)
require.NoError(t, err)

// native_to_relaxed_extended_json(json_to_native(rEJ)) = rEJ
nativeToJSON(t, rEJ, doc, v.Description, "relaxed", "eJR", "json_to_native(rEJ)")
}

/*** canonical extended JSON round-trip tests ***/
doc = jsonToNative(t, cEJ, "canonical", v.Description)
doc, err = jsonToNative(cEJ, "canonical", v.Description)
require.NoError(t, err)

// native_to_canonical_extended_json(json_to_native(cEJ)) = cEJ
nativeToJSON(t, cEJ, doc, v.Description, "canonical", "cEJ", "json_to_native(cEJ)")
Expand Down Expand Up @@ -295,7 +373,8 @@ func runTest(t *testing.T, file string) {
dEJ = normalizeCanonicalDouble(t, *test.TestKey, dEJ)
}

doc = jsonToNative(t, dEJ, "degenerate canonical", v.Description)
doc, err = jsonToNative(dEJ, "degenerate canonical", v.Description)
require.NoError(t, err)

// native_to_canonical_extended_json(json_to_native(dEJ)) = cEJ
nativeToJSON(t, cEJ, doc, v.Description, "degenerate canonical", "cEJ", "json_to_native(dEJ)")
Expand Down Expand Up @@ -366,7 +445,12 @@ func runTest(t *testing.T, file string) {
}

func Test_BsonCorpus(t *testing.T) {
for _, file := range findJSONFilesInDir(t, dataDir) {
jsonFiles, err := findJSONFilesInDir(dataDir)
if err != nil {
t.Fatalf("error finding JSON files in %s: %v", dataDir, err)
}

for _, file := range jsonFiles {
runTest(t, file)
}
}
Expand Down
34 changes: 34 additions & 0 deletions bson/fuzz_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package bson

import (
"testing"
)

func FuzzDecode(f *testing.F) {
seedBSONCorpus(f)

f.Fuzz(func(t *testing.T, data []byte) {
for _, typ := range []func() interface{}{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not loop over []interface{}? Is there a reason I'm not seeing for using these constructors?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a practice I took from the Go team. I think the idea is to make the type instantiation more realistic, i.e. something like this:

x := interface{} // or in our case typ()
// unmarshal into &x

And not like

for _, x := range []interface{ ... } {
// unmarshal into &x
}

func() interface{} { return new(D) },
func() interface{} { return new([]E) },
func() interface{} { return new(M) },
func() interface{} { return new(interface{}) },
func() interface{} { return make(map[string]interface{}) },
func() interface{} { return new([]interface{}) },
} {
i := typ()
if err := Unmarshal(data, i); err != nil {
return
}

encoded, err := Marshal(i)
if err != nil {
t.Fatal("failed to marshal", err)
}

if err := Unmarshal(encoded, i); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah interesting that we unmarshal, marshal and unmarshal again. What's the reasoning there?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first unmarshal is to check the validity of the extended JSON. We only want this to generate corpus data on a panic/crash. If the value is not valid BSON and we don't crash, then this subtest if over.

The first marshal is to check that we can encode valid data structures into BSON, it seems unnecessary to fuzz the encoding of invalid data structures.

The last unmarshal is where we check that we can decode valid BSON, if this fails/panics/crashes then we want to know about it.

t.Fatal("failed to unmarshal", err)
}
}
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("\x10\x00\x00\x00\v\x00\x00\x00\b\x00\x00\v\x00\x00\x00\x00")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these testdata/fuzz/FuzzDecode files separate from the bson-corpus seeds? How are these added into the seed corpus?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This data is different from testdata/bson-corpus. Three of these were interesting cases generated by running the fuzzer. One is BSON that encapsulates all types for an initial maximum code coverage in the style of the encoding/json fuzz test.

From the documentation:

seed corpus: A user-provided corpus for a fuzz test which can be used to guide the fuzzing engine. It is composed of the corpus entries provided by f.Add calls within the fuzz test, and the files in the testdata/fuzz/{FuzzTestName} directory within the package. These entries are run by default with go test, whether fuzzing or not.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thanks for the explanation.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0\\x00\\x00\\x00\\x0f\\x00000\\x8a00000000000000000000000000000000000000\n")
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("\\x80\\x00\\x00\\x00\\x03000000\\x00s\\x00\\x00\\x00\\x0300000\\x00g\\x00\\x00\\x00\\x100z\\x000000\\x11\\x00000\\x150000\\x020\\x00\\x02\\x00\\x00\\x000\\x12\\x00\\x050\\x00\\x01\\x00\\x00\\x0000\\x050\\x00\\x01\\x00\\x00\\x0000\\x040\\x00200000\\x00\\x000\\x02\\x00\\x10\\x0000000\\x110\\x0000000000\\x020\\x00\\x02\\x00\\x00\\x000\\x00\\x050\\x00\\x01\\x00\\x00\\x0000\\x050\\x00\\x01\\x00\\x00\\x0000\\x00\\x00\\x00\\x00\n")
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("\\x59\\x01\\x00\\x00\\x01\\x64\\x6f\\x75\\x62\\x6c\\x65\\x00\\x9a\\x99\\x99\\x99\\x99\\x99\\xf1\\x3f\\x02\\x73\\x74\\x72\\x69\\x6e\\x67\\x00\\x06\\x00\\x00\\x00\\x68\\x65\\x6c\\x6c\\x6f\\x00\\x03\\x65\\x6d\\x62\\x65\\x64\\x64\\x65\\x64\\x00\\x4b\\x00\\x00\\x00\\x04\\x61\\x72\\x72\\x61\\x79\\x00\\x3f\\x00\\x00\\x00\\x10\\x30\\x00\\x01\\x00\\x00\\x00\\x01\\x31\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x40\\x02\\x32\\x00\\x02\\x00\\x00\\x00\\x33\\x00\\x04\\x33\\x00\\x0c\\x00\\x00\\x00\\x10\\x30\\x00\\x04\\x00\\x00\\x00\\x00\\x03\\x34\\x00\\x0d\\x00\\x00\\x00\\x03\\x35\\x00\\x05\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x05\\x62\\x69\\x6e\\x61\\x72\\x79\\x00\\x03\\x00\\x00\\x00\\x00\\x01\\x02\\x03\\x07\\x6f\\x62\\x6a\\x65\\x63\\x74\\x69\\x64\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x08\\x62\\x6f\\x6f\\x6c\\x65\\x61\\x6e\\x00\\x01\\x09\\x64\\x61\\x74\\x65\\x74\\x69\\x6d\\x65\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x0a\\x6e\\x75\\x6c\\x6c\\x00\\x0b\\x72\\x65\\x67\\x65\\x78\\x00\\x68\\x65\\x6c\\x6c\\x6f\\x00\\x69\\x00\\x0d\\x6a\\x73\\x00\\x0e\\x00\\x00\\x00\\x66\\x75\\x6e\\x63\\x74\\x69\\x6f\\x6e\\x28\\x29\\x20\\x7b\\x7d\\x00\\x0f\\x73\\x63\\x6f\\x70\\x65\\x00\\x2c\\x00\\x00\\x00\\x0e\\x00\\x00\\x00\\x66\\x75\\x6e\\x63\\x74\\x69\\x6f\\x6e\\x28\\x29\\x20\\x7b\\x7d\\x00\\x16\\x00\\x00\\x00\\x02\\x68\\x65\\x6c\\x6c\\x6f\\x00\\x06\\x00\\x00\\x00\\x77\\x6f\\x72\\x6c\\x64\\x00\\x00\\x10\\x69\\x6e\\x74\\x33\\x32\\x00\\x20\\x00\\x00\\x00\\x11\\x74\\x69\\x6d\\x65\\x73\\x74\\x61\\x6d\\x70\\x00\\x02\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x12\\x69\\x6e\\x74\\x36\\x34\\x00\\x40\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xff\\x6d\\x69\\x6e\\x6b\\x65\\x79\\x00\\x7f\\x6d\\x61\\x78\\x6b\\x65\\x79\\x00\\x00\"\n")
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("\\x05\\xf0\\xff\\x00\\x7f\n")