Skip to content

Commit

Permalink
Fuzz parser with go-fuzz and GitHub Actions
Browse files Browse the repository at this point in the history
  • Loading branch information
tie committed Oct 16, 2020
1 parent 375ed7a commit 4b4a54e
Show file tree
Hide file tree
Showing 8 changed files with 380 additions and 0 deletions.
120 changes: 120 additions & 0 deletions .github/workflows/test-fuzz.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
name: Fuzz
on:
push:
pull_request:
workflow_dispatch:

jobs:
run:
name: Run
runs-on: ubuntu-latest
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
GOFLAGS: '-trimpath -mod=readonly'
GO111MODULE: 'on'
strategy:
fail-fast: false
matrix:
go:
# Misplaced compiler directive error with Go 1.15.x.
# https://github.com/dvyukov/go-fuzz/issues/294
- 1.14.x
goos:
- linux
goarch:
- amd64
func:
- FuzzParseQuery
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
path: genji

- name: Checkout corpus
uses: actions/checkout@v2
with:
repository: genjidb/go-fuzz-corpus
path: genji/fuzz/testdata/fuzz

- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go }}

- name: Get cache path
# FIXME use GOMODCACHE instead of GOPATH once
# https://github.com/dvyukov/go-fuzz/issues/294
# is fixed and we can bump Go to 1.15 or greater.
run: echo "::set-output name=dir::$(go env GOPATH)"
id: modcache

- name: Set up cache
uses: actions/cache@v2
with:
# FIXME remove -fuzz- once we can use GOMODCACHE
path: ${{ steps.modcache.outputs.dir }}
key: modcache-fuzz-${{ matrix.goos }}-${{ matrix.goarch }}-${{ hashFiles('**/go.sum') }}
restore-keys: modcache-fuzz-

- name: Download dependencies
run: go mod download
working-directory: genji/fuzz

# Using libFuzzer
#
# - https://github.com/mdempsky/go114-fuzz-build
# https://google.github.io/oss-fuzz/getting-started/new-project-guide/go-lang/
#
# go114-fuzz-build -o fuzz.a .
# clang -fsanitize=fuzzer -o fuzz fuzz.a
#
# - https://github.com/dvyukov/go-fuzz#libfuzzer-support
#
# go-fuzz-build -libfuzzer -o fuzz.a
# clang -fsanitize=fuzzer -o fuzz fuzz.a
#
# ./fuzz -max_len=1024 -max_total_time=300 corpus
#
# I haven’t tried go114-fuzz-build which uses builtin Go libFuzzer support,
# but I’ve had a better experience with go-fuzz vs libFuzzer without corpus.

- name: Run tests
run: |
go run github.com/dvyukov/go-fuzz/go-fuzz-build -func ${{ matrix.func }} && timeout -s INT -k 30 300 \
go run github.com/dvyukov/go-fuzz/go-fuzz -workdir=testdata/fuzz/${{ matrix.func }} -dumpcover
working-directory: genji/fuzz

- name: Prepare report
if: ${{ success() || failure() }}
id: report
run: |
mv testdata/fuzz/${{ matrix.func }}/coverprofile coverprofile-coverage.out
mv testdata/fuzz/${{ matrix.func }}/sonarprofile sonarprofile-coverage.out
# go-fuzz dumps coverage profiles that are not reproducible.
# We fix that by trimming absolute paths.
perl -pi -e '
s:^/opt/.*/src/::;
s:^/home/.*/mod/(.*)@[^/]*:\1:;
s:^/home/.*(?!/cmd)/genji/:github.com/genjidb/genji/:;
' coverprofile-coverage.out sonarprofile-coverage.out
# https://github.com/dvyukov/go-fuzz/issues/170#issuecomment-462297614
perl -ni -e 'print unless /0.0,1.1/' coverprofile-coverage.out
working-directory: genji/fuzz

- name: Upload coverage
if: ${{ success() || failure() }}
uses: actions/upload-artifact@v2
with:
name: ${{ matrix.func }}_cover_go${{ matrix.go }}
path: genji/fuzz/*coverage.*

- name: Upload corpus
if: ${{ success() || failure() }}
uses: actions/upload-artifact@v2
with:
name: ${{ matrix.func }}_corpus
path: genji/fuzz/testdata/fuzz/${{ matrix.func }}
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/genjidb/genji)
[![Slack channel](https://img.shields.io/badge/slack-join%20chat-green.svg)](https://gophers.slack.com/messages/CKPCYQFE0)

![Fuzz](https://github.com/genjidb/genji/workflows/Fuzz/badge.svg)
![macOS](https://github.com/genjidb/genji/workflows/macOS/badge.svg)
![Windows](https://github.com/genjidb/genji/workflows/Windows/badge.svg)
![Ubuntu](https://github.com/genjidb/genji/workflows/Ubuntu/badge.svg)

Genji is a schemaless database that allows running SQL queries on documents.

Checkout the [SQL documentation](https://genji.dev/docs/genji-sql), the [Go doc](https://pkg.go.dev/github.com/genjidb/genji) and the [usage example](#usage) in the README to get started quickly.
Expand Down
38 changes: 38 additions & 0 deletions fuzz/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Fuzz Tests

Fuzzing Genji with [go-fuzz](https://github.com/dvyukov/go-fuzz).

## Quick Start

1. Install [go-fuzz](https://github.com/dvyukov/go-fuzz)
```
go install github.com/dvyukov/go-fuzz/go-fuzz-build github.com/dvyukov/go-fuzz/go-fuzz
```

2. Download the initial corpus
```
git clone https://github.com/genjidb/go-fuzz-corpus testdata/fuzz
```

3. Build the test program with necessary instrumentation
```
go-fuzz-build -func FuzzParseQuery
```
This will produce fuzz-fuzz.zip archive.

4. Run the fuzzer.
```
go-fuzz -workdir=testdata/fuzz/FuzzParseQuery
```
The results will be written to `testdata/fuzz/FuzzParseQuery`.
Note that go-fuzz runs forever until manually stopped.

Example output:
```
2020/10/14 12:03:58 workers: 2, corpus: 166 (13s ago), crashers: 2, restarts: 1/9663, execs: 1526845 (16418/sec), cover: 924, uptime: 1m33s
```
Here, `corpus` is number of interesting inputs the fuzzer has discovered, and `crashers` is number of discovered bugs (check out `testdata/fuzz/FuzzParseQuery/crashers` dir).

See [README file from go-fuzz](https://github.com/dvyukov/go-fuzz/blob/master/README.md) for more information.
96 changes: 96 additions & 0 deletions fuzz/fuzz_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package fuzz

import (
"io/ioutil"
"os"
"path/filepath"
"reflect"
"runtime"
"strings"
"testing"
)

func TestFuzzParseQuery(t *testing.T) { testFuzz(t, FuzzParseQuery) }

func TestFuncName(t *testing.T) {
got := funcName(funcName)
expected := "funcName"
if got != expected {
t.Errorf("funcName(%s): expected %q, got %q", expected, expected, got)
}
}

// funcName returns the name of a function f.
// It is used to infer the workdir of a fuzz function.
func funcName(f interface{}) string {
v := reflect.ValueOf(f)
pc := v.Pointer()
fn := runtime.FuncForPC(pc)
name := fn.Name()
return name[strings.LastIndex(name, ".")+1:]
}

// testFuzz runs fuzz function once for each input in corpus.
// It assumes the directory structure from github.com/thepudds/fzgo.
// That is, testdata/fuzz/<FuzzName>/corpus stores the corpus.
func testFuzz(t *testing.T, fuzz func([]byte) int) {
t.Helper()

name := funcName(fuzz)

workdir := filepath.Join("testdata", "fuzz", name)
corpus := filepath.Join(workdir, "corpus")
crashers := filepath.Join(workdir, "crashers")

walkFn := func(path string, info os.FileInfo, err error) error {
t.Helper()

if err != nil {
// Do nothing if the root directory does not exist.
// Note that we expect testdata to be immutable
// while running tests (but not fuzzing).
if os.IsNotExist(err) {
return nil
}
return err
}

// Don’t descend into subdirectories.
if info.IsDir() && path != corpus && path != crashers {
return filepath.SkipDir
}

if !info.Mode().IsRegular() {
return nil
}

// Skip debug info in crashers directory.
if path == crashers {
if strings.HasSuffix(path, ".output") || strings.HasSuffix(path, ".quoted") {
return nil
}
}

t.Run(info.Name(), func(t *testing.T) {
t.Helper()

data, err := ioutil.ReadFile(path)
if err != nil {
t.Errorf("read test data: %v", err)
return
}

fuzz(data)
})

return nil
}

roots := []string{corpus, crashers}
for _, root := range roots {
err := filepath.Walk(root, walkFn)
if err != nil {
t.Errorf("walk %q: %v", root, err)
}
}
}
13 changes: 13 additions & 0 deletions fuzz/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module github.com/genjidb/genji/fuzz

go 1.15

require (
github.com/dvyukov/go-fuzz v0.0.0-20201003075337-90825f39c90b
github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect
github.com/genjidb/genji v0.9.0
github.com/stephens2424/writerset v1.0.2 // indirect
golang.org/x/tools v0.0.0-20201013053347-2db1cd791039 // indirect
)

replace github.com/genjidb/genji v0.9.0 => ../
77 changes: 77 additions & 0 deletions fuzz/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
github.com/Julusian/godocdown v0.0.0-20170816220326-6d19f8ff2df8/go.mod h1:INZr5t32rG59/5xeltqoCJoNY7e5x/3xoY9WSWVWg74=
github.com/buger/jsonparser v1.0.0 h1:etJTGF5ESxjI0Ic2UaLQs2LQQpa8G9ykQScukbh4L8A=
github.com/buger/jsonparser v1.0.0/go.mod h1:tgcrVJ81GPSF0mz+0nu1Xaz0fazGPrmmJfJtxjbHhUQ=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dvyukov/go-fuzz v0.0.0-20201003075337-90825f39c90b h1:CXfDl9Y3NKuhOSxF9kXhiLmuYCdufQDrLY2fO1BzqBU=
github.com/dvyukov/go-fuzz v0.0.0-20201003075337-90825f39c90b/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
github.com/elazarl/go-bindata-assetfs v1.0.1/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s=
github.com/stephens2424/writerset v1.0.2 h1:znRLgU6g8RS5euYRcy004XeE4W+Tu44kALzy7ghPif8=
github.com/stephens2424/writerset v1.0.2/go.mod h1:aS2JhsMn6eA7e82oNmW4rfsgAOp9COBTTl8mzkwADnc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/vmihailenco/msgpack/v4 v4.3.11/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
github.com/vmihailenco/msgpack/v5 v5.0.0-beta.1 h1:d71/KA0LhvkrJ/Ok+Wx9qK7bU8meKA1Hk0jpVI5kJjk=
github.com/vmihailenco/msgpack/v5 v5.0.0-beta.1/go.mod h1:xlngVLeyQ/Qi05oQxhQ+oTuqa03RjMwMfk/7/TCs+QI=
github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY=
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20201013053347-2db1cd791039 h1:kLBxO4OPBgPwjg8Vvu+/0DCHIfDwYIGNFcD66NU9kpo=
golang.org/x/tools v0.0.0-20201013053347-2db1cd791039/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
21 changes: 21 additions & 0 deletions fuzz/sqlparser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package fuzz

import (
"context"
"strings"

"github.com/genjidb/genji/sql/parser"
)

func FuzzParseQuery(data []byte) int {
var b strings.Builder
b.Write(data)
q, err := parser.ParseQuery(context.Background(), b.String())
if err != nil {
return 0
}
if len(q.Statements) != 0 {
return 1
}
return 0
}
10 changes: 10 additions & 0 deletions fuzz/tools.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// +build tools

package fuzz

// Makes `go mod tidy` keep tool dependencies in go.mod and go.sum.

import (
_ "github.com/dvyukov/go-fuzz/go-fuzz"
_ "github.com/dvyukov/go-fuzz/go-fuzz-build"
)

0 comments on commit 4b4a54e

Please sign in to comment.