diff options
| author | kmoe <5575356+kmoe@users.noreply.github.com> | 2022-06-21 14:35:40 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-21 14:35:40 +0100 |
| commit | 986b8816d5d38d6b71f9083d7f03ee702d85d5f7 (patch) | |
| tree | 1f81f224cc9405f1bd13a30d70fcb49249a485b2 | |
| parent | c3b671524ef9402b2837c2fd14a4ed115fc69772 (diff) | |
| parent | c020cb984b9deb3e9fa7593af2782ae57c7fa149 (diff) | |
Merge pull request #508 from hashicorp/go118fuzz
Port fuzz testing to Go 1.18 native fuzzing
153 files changed, 348 insertions, 392 deletions
diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 423ef28..b9e4346 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -29,6 +29,10 @@ jobs: git config --global core.autocrlf false - name: "Fetch source code" uses: actions/checkout@v2 + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: 1.18 - name: Go test run: | go test ./... @@ -40,6 +44,10 @@ jobs: steps: - name: "Fetch source code" uses: actions/checkout@v2 + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: 1.18 - name: "Check vet" run: | go vet ./... diff --git a/hclsyntax/fuzz/README.md b/hclsyntax/fuzz/README.md index 7ffbc0d..a6fca75 100644 --- a/hclsyntax/fuzz/README.md +++ b/hclsyntax/fuzz/README.md @@ -1,85 +1,62 @@ # hclsyntax fuzzing utilities -This directory contains helper functions and corpuses that can be used to -fuzz-test the `hclsyntax` parsers using [go-fuzz](https://github.com/dvyukov/go-fuzz). +This directory contains helper functions and corpora that can be used to +fuzz-test the `hclsyntax` parsers using Go's native fuzz testing capabilities. -## Work directory +Please see https://go.dev/doc/fuzz/ for more information on fuzzing. -`go-fuzz` needs a working directory where it can keep state as it works. This -should ideally be in a ramdisk for efficiency, and should probably _not_ be on -an SSD to avoid thrashing it. Here's how to create a ramdisk: +## Prerequisites +* Go 1.18 -### macOS - -``` -$ SIZE_IN_MB=1024 -$ DEVICE=`hdiutil attach -nobrowse -nomount ram://$(($SIZE_IN_MB*2048))` -$ diskutil erasevolume HFS+ RamDisk $DEVICE -$ export RAMDISK=/Volumes/RamDisk -``` +## Running the fuzzer -### Linux +Each exported function in the `hclsyntax` package has a corresponding fuzz test. +These can be run one at a time via `go test`: ``` -$ mkdir /mnt/ramdisk -$ mount -t tmpfs -o size=1024M tmpfs /mnt/ramdisk -$ export RAMDISK=/mnt/ramdisk +$ cd fuzz +$ go test -fuzz FuzzParseTemplate +$ go test -fuzz FuzzParseTraversalAbs +$ go test -fuzz FuzzParseExpression +$ go test -fuzz FuzzParseConfig ``` -## Running the fuzzer +This command will exit only when a crasher is found (see "Understanding the +result" below.) + +## Seed corpus -Next, install `go-fuzz` and its build tool in your `GOPATH`: +The seed corpus for each fuzz test function is stored in the corresponding +directory under `hclsyntax/fuzz/testdata/fuzz/`. For example: ``` -$ make tools FUZZ_WORK_DIR=$RAMDISK +$ ls hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate +empty.tmpl +escape-dollar.tmpl +escape-newline-tmpl +... ``` -Now you can fuzz one or all of the parsers: +Additional seed inputs can be added to this corpus. Each file must be in the Go 1.18 corpus file format. Files can be converted to this format using the `file2fuzz` tool. To install it: ``` -$ make fuzz-config FUZZ_WORK_DIR=$RAMDISK/hclsyntax-fuzz-config -$ make fuzz-expr FUZZ_WORK_DIR=$RAMDISK/hclsyntax-fuzz-expr -$ make fuzz-template FUZZ_WORK_DIR=$RAMDISK/hclsyntax-fuzz-template -$ make fuzz-traversal FUZZ_WORK_DIR=$RAMDISK/hclsyntax-fuzz-traversal +$ go install golang.org/x/tools/cmd/file2fuzz@latest +$ file2fuzz -help ``` -~> Note: `go-fuzz` does not interact well with `goenv`. If you encounter build -errors where the package `go.fuzz.main` could not be found, you may need to use -a machine with a direct installation of Go. - ## Understanding the result A small number of subdirectories will be created in the work directory. If you let `go-fuzz` run for a few minutes (the more minutes the better) it -may detect "crashers", which are inputs that caused the parser to panic. Details -about these are written to `$FUZZ_WORK_DIR/crashers`: +may detect "crashers", which are inputs that caused the parser to panic. +These are written to `hclsyntax/fuzz/testdata/fuzz/<fuzz test name>/`: ``` -$ ls /tmp/hcl2-fuzz-config/crashers -7f5e9ec80c89da14b8b0b238ec88969f658f5a2d -7f5e9ec80c89da14b8b0b238ec88969f658f5a2d.output -7f5e9ec80c89da14b8b0b238ec88969f658f5a2d.quoted +$ ls hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate +582528ddfad69eb57775199a43e0f9fd5c94bba343ce7bb6724d4ebafe311ed4 ``` -The base file above (with no extension) is the input that caused a crash. The -`.output` file contains the panic stack trace, which you can use as a clue to -figure out what caused the crash. - A good first step to fixing a detected crasher is to copy the failing input into one of the unit tests in the `hclsyntax` package and see it crash there -too. After that, it's easy to re-run the test as you try to fix it. The -file with the `.quoted` extension contains a form of the input that is quoted -in Go syntax for easy copy-paste into a test case, even if the input contains -non-printable characters or other inconvenient symbols. - -## Rebuilding for new Upstream Code - -An archive file is created for `go-fuzz` to use on the first run of each -of the above, as a `.zip` file created in this directory. If upstream code -is changed these will need to be deleted to cause them to be rebuilt with -the latest code: - -``` -$ make clean -``` +too. After that, it's easy to re-run the test as you try to fix it. diff --git a/hclsyntax/fuzz/config/corpus/attr-expr.hcl b/hclsyntax/fuzz/config/corpus/attr-expr.hcl deleted file mode 100644 index 908bbc9..0000000 --- a/hclsyntax/fuzz/config/corpus/attr-expr.hcl +++ /dev/null @@ -1 +0,0 @@ -foo = upper(bar + baz[1]) diff --git a/hclsyntax/fuzz/config/corpus/attr-literal.hcl b/hclsyntax/fuzz/config/corpus/attr-literal.hcl deleted file mode 100644 index 5abc475..0000000 --- a/hclsyntax/fuzz/config/corpus/attr-literal.hcl +++ /dev/null @@ -1 +0,0 @@ -foo = "bar" diff --git a/hclsyntax/fuzz/config/corpus/block-attrs.hcl b/hclsyntax/fuzz/config/corpus/block-attrs.hcl deleted file mode 100644 index eb529ef..0000000 --- a/hclsyntax/fuzz/config/corpus/block-attrs.hcl +++ /dev/null @@ -1,3 +0,0 @@ -block { - foo = true -} diff --git a/hclsyntax/fuzz/config/corpus/block-empty.hcl b/hclsyntax/fuzz/config/corpus/block-empty.hcl deleted file mode 100644 index b3b13a1..0000000 --- a/hclsyntax/fuzz/config/corpus/block-empty.hcl +++ /dev/null @@ -1,2 +0,0 @@ -block { -} diff --git a/hclsyntax/fuzz/config/corpus/block-nested.hcl b/hclsyntax/fuzz/config/corpus/block-nested.hcl deleted file mode 100644 index 304183a..0000000 --- a/hclsyntax/fuzz/config/corpus/block-nested.hcl +++ /dev/null @@ -1,5 +0,0 @@ -block { - another_block { - foo = bar - } -} diff --git a/hclsyntax/fuzz/config/corpus/empty.hcl b/hclsyntax/fuzz/config/corpus/empty.hcl deleted file mode 100644 index e69de29..0000000 --- a/hclsyntax/fuzz/config/corpus/empty.hcl +++ /dev/null diff --git a/hclsyntax/fuzz/config/corpus/utf8.hcl b/hclsyntax/fuzz/config/corpus/utf8.hcl deleted file mode 100644 index ffad4b0..0000000 --- a/hclsyntax/fuzz/config/corpus/utf8.hcl +++ /dev/null @@ -1 +0,0 @@ -foo = "föo ${föo("föo")}" diff --git a/hclsyntax/fuzz/config/fuzz.go b/hclsyntax/fuzz/config/fuzz.go deleted file mode 100644 index 798fa37..0000000 --- a/hclsyntax/fuzz/config/fuzz.go +++ /dev/null @@ -1,16 +0,0 @@ -package fuzzconfig - -import ( - "github.com/hashicorp/hcl/v2" - "github.com/hashicorp/hcl/v2/hclsyntax" -) - -func Fuzz(data []byte) int { - _, diags := hclsyntax.ParseConfig(data, "<fuzz-conf>", hcl.Pos{Line: 1, Column: 1}) - - if diags.HasErrors() { - return 0 - } - - return 1 -} diff --git a/hclsyntax/fuzz/expr/corpus/empty.hcle b/hclsyntax/fuzz/expr/corpus/empty.hcle deleted file mode 100644 index 3cc762b..0000000 --- a/hclsyntax/fuzz/expr/corpus/empty.hcle +++ /dev/null @@ -1 +0,0 @@ -""
\ No newline at end of file diff --git a/hclsyntax/fuzz/expr/corpus/escape-dollar.hcle b/hclsyntax/fuzz/expr/corpus/escape-dollar.hcle deleted file mode 100644 index 418c716..0000000 --- a/hclsyntax/fuzz/expr/corpus/escape-dollar.hcle +++ /dev/null @@ -1 +0,0 @@ -"hi $${var.foo}"
\ No newline at end of file diff --git a/hclsyntax/fuzz/expr/corpus/escape-newline.hcle b/hclsyntax/fuzz/expr/corpus/escape-newline.hcle deleted file mode 100644 index 746d917..0000000 --- a/hclsyntax/fuzz/expr/corpus/escape-newline.hcle +++ /dev/null @@ -1 +0,0 @@ -"bar\nbaz" diff --git a/hclsyntax/fuzz/expr/corpus/function-call.hcle b/hclsyntax/fuzz/expr/corpus/function-call.hcle deleted file mode 100644 index 23b5602..0000000 --- a/hclsyntax/fuzz/expr/corpus/function-call.hcle +++ /dev/null @@ -1 +0,0 @@ -title(var.name)
\ No newline at end of file diff --git a/hclsyntax/fuzz/expr/corpus/int.hcle b/hclsyntax/fuzz/expr/corpus/int.hcle deleted file mode 100644 index f70d7bb..0000000 --- a/hclsyntax/fuzz/expr/corpus/int.hcle +++ /dev/null @@ -1 +0,0 @@ -42
\ No newline at end of file diff --git a/hclsyntax/fuzz/expr/corpus/literal.hcle b/hclsyntax/fuzz/expr/corpus/literal.hcle deleted file mode 100644 index 1910281..0000000 --- a/hclsyntax/fuzz/expr/corpus/literal.hcle +++ /dev/null @@ -1 +0,0 @@ -foo
\ No newline at end of file diff --git a/hclsyntax/fuzz/expr/corpus/splat-attr.hcle b/hclsyntax/fuzz/expr/corpus/splat-attr.hcle deleted file mode 100644 index 9fdbccd..0000000 --- a/hclsyntax/fuzz/expr/corpus/splat-attr.hcle +++ /dev/null @@ -1 +0,0 @@ -foo.bar.*.baz diff --git a/hclsyntax/fuzz/expr/corpus/splat-full.hcle b/hclsyntax/fuzz/expr/corpus/splat-full.hcle deleted file mode 100644 index 5c66c9f..0000000 --- a/hclsyntax/fuzz/expr/corpus/splat-full.hcle +++ /dev/null @@ -1 +0,0 @@ -foo.bar[*].baz diff --git a/hclsyntax/fuzz/expr/corpus/utf8.hcle b/hclsyntax/fuzz/expr/corpus/utf8.hcle deleted file mode 100644 index c45f694..0000000 --- a/hclsyntax/fuzz/expr/corpus/utf8.hcle +++ /dev/null @@ -1 +0,0 @@ -föo("föo") + föo
\ No newline at end of file diff --git a/hclsyntax/fuzz/expr/corpus/var.hcle b/hclsyntax/fuzz/expr/corpus/var.hcle deleted file mode 100644 index a88d495..0000000 --- a/hclsyntax/fuzz/expr/corpus/var.hcle +++ /dev/null @@ -1 +0,0 @@ -var.bar
\ No newline at end of file diff --git a/hclsyntax/fuzz/expr/fuzz.go b/hclsyntax/fuzz/expr/fuzz.go deleted file mode 100644 index 12708e8..0000000 --- a/hclsyntax/fuzz/expr/fuzz.go +++ /dev/null @@ -1,16 +0,0 @@ -package fuzzexpr - -import ( - "github.com/hashicorp/hcl/v2" - "github.com/hashicorp/hcl/v2/hclsyntax" -) - -func Fuzz(data []byte) int { - _, diags := hclsyntax.ParseExpression(data, "<fuzz-expr>", hcl.Pos{Line: 1, Column: 1}) - - if diags.HasErrors() { - return 0 - } - - return 1 -} diff --git a/hclsyntax/fuzz/fuzz_test.go b/hclsyntax/fuzz/fuzz_test.go new file mode 100644 index 0000000..4f0d153 --- /dev/null +++ b/hclsyntax/fuzz/fuzz_test.go @@ -0,0 +1,60 @@ +package fuzzhclsyntax + +import ( + "testing" + + "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/hcl/v2/hclsyntax" +) + +func FuzzParseTemplate(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + _, diags := hclsyntax.ParseTemplate(data, "<fuzz-tmpl>", hcl.Pos{Line: 1, Column: 1}) + + if diags.HasErrors() { + t.Logf("Error when parsing template %v", data) + for _, diag := range diags { + t.Logf("- %s", diag.Error()) + } + } + }) +} + +func FuzzParseTraversalAbs(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + _, diags := hclsyntax.ParseTraversalAbs(data, "<fuzz-trav>", hcl.Pos{Line: 1, Column: 1}) + + if diags.HasErrors() { + t.Logf("Error when parsing traversal %v", data) + for _, diag := range diags { + t.Logf("- %s", diag.Error()) + } + } + }) +} + +func FuzzParseExpression(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + _, diags := hclsyntax.ParseExpression(data, "<fuzz-expr>", hcl.Pos{Line: 1, Column: 1}) + + if diags.HasErrors() { + t.Logf("Error when parsing expression %v", data) + for _, diag := range diags { + t.Logf("- %s", diag.Error()) + } + } + }) +} + +func FuzzParseConfig(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + _, diags := hclsyntax.ParseConfig(data, "<fuzz-conf>", hcl.Pos{Line: 1, Column: 1}) + + if diags.HasErrors() { + t.Logf("Error when parsing config %v", data) + for _, diag := range diags { + t.Logf("- %s", diag.Error()) + } + } + }) +} diff --git a/hclsyntax/fuzz/template/corpus/empty.tmpl b/hclsyntax/fuzz/template/corpus/empty.tmpl deleted file mode 100644 index e69de29..0000000 --- a/hclsyntax/fuzz/template/corpus/empty.tmpl +++ /dev/null diff --git a/hclsyntax/fuzz/template/corpus/escape-dollar.tmpl b/hclsyntax/fuzz/template/corpus/escape-dollar.tmpl deleted file mode 100644 index ec6ebc7..0000000 --- a/hclsyntax/fuzz/template/corpus/escape-dollar.tmpl +++ /dev/null @@ -1 +0,0 @@ -hi $${var.foo}
\ No newline at end of file diff --git a/hclsyntax/fuzz/template/corpus/escape-newline.tmpl b/hclsyntax/fuzz/template/corpus/escape-newline.tmpl deleted file mode 100644 index dc5c9fc..0000000 --- a/hclsyntax/fuzz/template/corpus/escape-newline.tmpl +++ /dev/null @@ -1 +0,0 @@ -foo ${"bar\nbaz"}
\ No newline at end of file diff --git a/hclsyntax/fuzz/template/corpus/function-call.tmpl b/hclsyntax/fuzz/template/corpus/function-call.tmpl deleted file mode 100644 index b4ee261..0000000 --- a/hclsyntax/fuzz/template/corpus/function-call.tmpl +++ /dev/null @@ -1 +0,0 @@ -hi ${title(var.name)}
\ No newline at end of file diff --git a/hclsyntax/fuzz/template/corpus/int.tmpl b/hclsyntax/fuzz/template/corpus/int.tmpl deleted file mode 100644 index 9337c90..0000000 --- a/hclsyntax/fuzz/template/corpus/int.tmpl +++ /dev/null @@ -1 +0,0 @@ -foo ${42}
\ No newline at end of file diff --git a/hclsyntax/fuzz/template/corpus/just-interp.tmpl b/hclsyntax/fuzz/template/corpus/just-interp.tmpl deleted file mode 100644 index 5c95825..0000000 --- a/hclsyntax/fuzz/template/corpus/just-interp.tmpl +++ /dev/null @@ -1 +0,0 @@ -${var.bar}
\ No newline at end of file diff --git a/hclsyntax/fuzz/template/corpus/literal.tmpl b/hclsyntax/fuzz/template/corpus/literal.tmpl deleted file mode 100644 index 1910281..0000000 --- a/hclsyntax/fuzz/template/corpus/literal.tmpl +++ /dev/null @@ -1 +0,0 @@ -foo
\ No newline at end of file diff --git a/hclsyntax/fuzz/template/corpus/utf8.tmpl b/hclsyntax/fuzz/template/corpus/utf8.tmpl deleted file mode 100644 index 8d4aa44..0000000 --- a/hclsyntax/fuzz/template/corpus/utf8.tmpl +++ /dev/null @@ -1 +0,0 @@ -föo ${föo("föo")}
\ No newline at end of file diff --git a/hclsyntax/fuzz/template/fuzz.go b/hclsyntax/fuzz/template/fuzz.go deleted file mode 100644 index d17963c..0000000 --- a/hclsyntax/fuzz/template/fuzz.go +++ /dev/null @@ -1,16 +0,0 @@ -package fuzztemplate - -import ( - "github.com/hashicorp/hcl/v2" - "github.com/hashicorp/hcl/v2/hclsyntax" -) - -func Fuzz(data []byte) int { - _, diags := hclsyntax.ParseTemplate(data, "<fuzz-tmpl>", hcl.Pos{Line: 1, Column: 1}) - - if diags.HasErrors() { - return 0 - } - - return 1 -} diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/attr-expr.hcl b/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/attr-expr.hcl new file mode 100644 index 0000000..7860981 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/attr-expr.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo = upper(bar + baz[1])\n")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/attr-literal.hcl b/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/attr-literal.hcl new file mode 100644 index 0000000..e4374f5 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/attr-literal.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo = \"bar\"\n")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/block-attrs.hcl b/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/block-attrs.hcl new file mode 100644 index 0000000..5751d05 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/block-attrs.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("block {\n foo = true\n}\n")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/block-empty.hcl b/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/block-empty.hcl new file mode 100644 index 0000000..ef0e91f --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/block-empty.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("block {\n}\n")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/block-nested.hcl b/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/block-nested.hcl new file mode 100644 index 0000000..0c2ed01 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/block-nested.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("block {\n another_block {\n foo = bar\n }\n}\n")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/empty.hcl b/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/empty.hcl new file mode 100644 index 0000000..e0f2da2 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/empty.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/utf8.hcl b/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/utf8.hcl new file mode 100644 index 0000000..85c4a70 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/utf8.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo = \"föo ${föo(\"föo\")}\"\n")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/empty.hcle b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/empty.hcle new file mode 100644 index 0000000..9824118 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/empty.hcle @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("\"\"")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/escape-dollar.hcle b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/escape-dollar.hcle new file mode 100644 index 0000000..5da4360 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/escape-dollar.hcle @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("\"hi $${var.foo}\"")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/escape-newline.hcle b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/escape-newline.hcle new file mode 100644 index 0000000..1ca59fc --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/escape-newline.hcle @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("\"bar\\nbaz\"\n")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/function-call.hcle b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/function-call.hcle new file mode 100644 index 0000000..1339b3d --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/function-call.hcle @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("title(var.name)")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/int.hcle b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/int.hcle new file mode 100644 index 0000000..69ec297 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/int.hcle @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("42")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/literal.hcle b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/literal.hcle new file mode 100644 index 0000000..66f7c5a --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/literal.hcle @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/splat-attr.hcle b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/splat-attr.hcle new file mode 100644 index 0000000..334ea39 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/splat-attr.hcle @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo.bar.*.baz\n")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/splat-full.hcle b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/splat-full.hcle new file mode 100644 index 0000000..e0e9a11 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/splat-full.hcle @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo.bar[*].baz\n")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/utf8.hcle b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/utf8.hcle new file mode 100644 index 0000000..77a3d32 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/utf8.hcle @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("föo(\"föo\") + föo")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/var.hcle b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/var.hcle new file mode 100644 index 0000000..d415660 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/var.hcle @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("var.bar")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/empty.tmpl b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/empty.tmpl new file mode 100644 index 0000000..e0f2da2 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/empty.tmpl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/escape-dollar.tmpl b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/escape-dollar.tmpl new file mode 100644 index 0000000..30f3df6 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/escape-dollar.tmpl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("hi $${var.foo}")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/escape-newline.tmpl b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/escape-newline.tmpl new file mode 100644 index 0000000..1d3d4fc --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/escape-newline.tmpl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo ${\"bar\\nbaz\"}")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/function-call.tmpl b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/function-call.tmpl new file mode 100644 index 0000000..5938919 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/function-call.tmpl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("hi ${title(var.name)}")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/int.tmpl b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/int.tmpl new file mode 100644 index 0000000..c3b4fb1 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/int.tmpl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo ${42}")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/just-interp.tmpl b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/just-interp.tmpl new file mode 100644 index 0000000..d95a359 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/just-interp.tmpl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("${var.bar}")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/literal.tmpl b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/literal.tmpl new file mode 100644 index 0000000..66f7c5a --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/literal.tmpl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/utf8.tmpl b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/utf8.tmpl new file mode 100644 index 0000000..a310452 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/utf8.tmpl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("föo ${föo(\"föo\")}")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/attr.hclt b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/attr.hclt new file mode 100644 index 0000000..c48bdd6 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/attr.hclt @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo.bar")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/complex.hclt b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/complex.hclt new file mode 100644 index 0000000..01976eb --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/complex.hclt @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo.bar[1].baz[\"foo\"].pizza")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/index.hclt b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/index.hclt new file mode 100644 index 0000000..4bd0b32 --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/index.hclt @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo[1]")
\ No newline at end of file diff --git a/hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/root.hclt b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/root.hclt new file mode 100644 index 0000000..66f7c5a --- /dev/null +++ b/hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/root.hclt @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo")
\ No newline at end of file diff --git a/hclsyntax/fuzz/traversal/corpus/attr.hclt b/hclsyntax/fuzz/traversal/corpus/attr.hclt deleted file mode 100644 index 4d5f975..0000000 --- a/hclsyntax/fuzz/traversal/corpus/attr.hclt +++ /dev/null @@ -1 +0,0 @@ -foo.bar
\ No newline at end of file diff --git a/hclsyntax/fuzz/traversal/corpus/complex.hclt b/hclsyntax/fuzz/traversal/corpus/complex.hclt deleted file mode 100644 index 1eb90f0..0000000 --- a/hclsyntax/fuzz/traversal/corpus/complex.hclt +++ /dev/null @@ -1 +0,0 @@ -foo.bar[1].baz["foo"].pizza
\ No newline at end of file diff --git a/hclsyntax/fuzz/traversal/corpus/index.hclt b/hclsyntax/fuzz/traversal/corpus/index.hclt deleted file mode 100644 index 83c639a..0000000 --- a/hclsyntax/fuzz/traversal/corpus/index.hclt +++ /dev/null @@ -1 +0,0 @@ -foo[1]
\ No newline at end of file diff --git a/hclsyntax/fuzz/traversal/corpus/root.hclt b/hclsyntax/fuzz/traversal/corpus/root.hclt deleted file mode 100644 index 1910281..0000000 --- a/hclsyntax/fuzz/traversal/corpus/root.hclt +++ /dev/null @@ -1 +0,0 @@ -foo
\ No newline at end of file diff --git a/hclsyntax/fuzz/traversal/fuzz.go b/hclsyntax/fuzz/traversal/fuzz.go deleted file mode 100644 index 856498f..0000000 --- a/hclsyntax/fuzz/traversal/fuzz.go +++ /dev/null @@ -1,16 +0,0 @@ -package fuzztraversal - -import ( - "github.com/hashicorp/hcl/v2" - "github.com/hashicorp/hcl/v2/hclsyntax" -) - -func Fuzz(data []byte) int { - _, diags := hclsyntax.ParseTraversalAbs(data, "<fuzz-trav>", hcl.Pos{Line: 1, Column: 1}) - - if diags.HasErrors() { - return 0 - } - - return 1 -} diff --git a/hclwrite/fuzz/README.md b/hclwrite/fuzz/README.md index 0e11623..63cffbb 100644 --- a/hclwrite/fuzz/README.md +++ b/hclwrite/fuzz/README.md @@ -1,82 +1,59 @@ # hclwrite fuzzing utilities -This directory contains helper functions and corpuses that can be used to -fuzz-test the `hclwrite` package using [go-fuzz](https://github.com/dvyukov/go-fuzz). +This directory contains helper functions and corpora that can be used to +fuzz-test the `hclwrite` parsers using Go's native fuzz testing capabilities. -## Work directory +Please see https://go.dev/doc/fuzz/ for more information on fuzzing. -`go-fuzz` needs a working directory where it can keep state as it works. This -should ideally be in a ramdisk for efficiency, and should probably _not_ be on -an SSD to avoid thrashing it. Here's how to create a ramdisk: +## Prerequisites +* Go 1.18 -### macOS - -``` -$ SIZE_IN_MB=1024 -$ DEVICE=`hdiutil attach -nobrowse -nomount ram://$(($SIZE_IN_MB*2048))` -$ diskutil erasevolume HFS+ RamDisk $DEVICE -$ export RAMDISK=/Volumes/RamDisk -``` +## Running the fuzzer -### Linux +Each exported function in the `hclwrite` package has a corresponding fuzz test. +These can be run one at a time via `go test`: ``` -$ mkdir /mnt/ramdisk -$ mount -t tmpfs -o size=1024M tmpfs /mnt/ramdisk -$ export RAMDISK=/mnt/ramdisk +$ cd fuzz +$ go test -fuzz FuzzParseConfig ``` -## Running the fuzzer +This command will exit only when a crasher is found (see "Understanding the +result" below.) + +## Seed corpus -Next, install `go-fuzz` and its build tool in your `GOPATH`: +The seed corpus for each fuzz test function is stored in the corresponding +directory under `hclwrite/fuzz/testdata/fuzz/FuzzTest`. For example: ``` -$ make tools FUZZ_WORK_DIR=$RAMDISK +$ ls hclwrite/fuzz/testdata/fuzz/FuzzParseConfig +attr-expr.hcl +attr.hcl +attr-literal.hcl +... ``` -Now you can fuzz the parser: +Additional seed inputs can be added to this corpus. Each file must be in the Go 1.18 corpus file format. Files can be converted to this format using the `file2fuzz` tool. To install it: ``` -$ make fuzz-config FUZZ_WORK_DIR=$RAMDISK/hclwrite-fuzz-config +$ go install golang.org/x/tools/cmd/file2fuzz@latest +$ file2fuzz -help ``` -~> Note: `go-fuzz` does not interact well with `goenv`. If you encounter build -errors where the package `go.fuzz.main` could not be found, you may need to use -a machine with a direct installation of Go. - ## Understanding the result A small number of subdirectories will be created in the work directory. If you let `go-fuzz` run for a few minutes (the more minutes the better) it -may detect "crashers", which are inputs that caused the parser to panic. Details -about these are written to `$FUZZ_WORK_DIR/crashers`: +may detect "crashers", which are inputs that caused the parser to panic. +These are written to `hclwrite/fuzz/testdata/fuzz/<fuzz test name>/`: ``` -$ ls /tmp/hcl2-fuzz-config/crashers -7f5e9ec80c89da14b8b0b238ec88969f658f5a2d -7f5e9ec80c89da14b8b0b238ec88969f658f5a2d.output -7f5e9ec80c89da14b8b0b238ec88969f658f5a2d.quoted +$ ls hclwrite/fuzz/testdata/fuzz/FuzzParseConfig +582528ddfad69eb57775199a43e0f9fd5c94bba343ce7bb6724d4ebafe311ed4 ``` -The base file above (with no extension) is the input that caused a crash. The -`.output` file contains the panic stack trace, which you can use as a clue to -figure out what caused the crash. - A good first step to fixing a detected crasher is to copy the failing input into one of the unit tests in the `hclwrite` package and see it crash there -too. After that, it's easy to re-run the test as you try to fix it. The -file with the `.quoted` extension contains a form of the input that is quoted -in Go syntax for easy copy-paste into a test case, even if the input contains -non-printable characters or other inconvenient symbols. - -## Rebuilding for new Upstream Code - -An archive file is created for `go-fuzz` to use on the first run of each -of the above, as a `.zip` file created in this directory. If upstream code -is changed these will need to be deleted to cause them to be rebuilt with -the latest code: - -``` -$ make clean -``` +too. After that, it's easy to re-run the test as you try to fix it. diff --git a/hclwrite/fuzz/config/corpus/attr-expr.hcl b/hclwrite/fuzz/config/corpus/attr-expr.hcl deleted file mode 100644 index 908bbc9..0000000 --- a/hclwrite/fuzz/config/corpus/attr-expr.hcl +++ /dev/null @@ -1 +0,0 @@ -foo = upper(bar + baz[1]) diff --git a/hclwrite/fuzz/config/corpus/attr-literal.hcl b/hclwrite/fuzz/config/corpus/attr-literal.hcl deleted file mode 100644 index 5abc475..0000000 --- a/hclwrite/fuzz/config/corpus/attr-literal.hcl +++ /dev/null @@ -1 +0,0 @@ -foo = "bar" diff --git a/hclwrite/fuzz/config/corpus/attr.hcl b/hclwrite/fuzz/config/corpus/attr.hcl deleted file mode 100644 index 6c11db6..0000000 --- a/hclwrite/fuzz/config/corpus/attr.hcl +++ /dev/null @@ -1 +0,0 @@ -a = foo.bar diff --git a/hclwrite/fuzz/config/corpus/block-attrs.hcl b/hclwrite/fuzz/config/corpus/block-attrs.hcl deleted file mode 100644 index eb529ef..0000000 --- a/hclwrite/fuzz/config/corpus/block-attrs.hcl +++ /dev/null @@ -1,3 +0,0 @@ -block { - foo = true -} diff --git a/hclwrite/fuzz/config/corpus/block-comment.hcl b/hclwrite/fuzz/config/corpus/block-comment.hcl deleted file mode 100644 index 9ed4c68..0000000 --- a/hclwrite/fuzz/config/corpus/block-comment.hcl +++ /dev/null @@ -1,4 +0,0 @@ -/* multi - line - comment -*/ diff --git a/hclwrite/fuzz/config/corpus/block-empty.hcl b/hclwrite/fuzz/config/corpus/block-empty.hcl deleted file mode 100644 index b3b13a1..0000000 --- a/hclwrite/fuzz/config/corpus/block-empty.hcl +++ /dev/null @@ -1,2 +0,0 @@ -block { -} diff --git a/hclwrite/fuzz/config/corpus/block-nested.hcl b/hclwrite/fuzz/config/corpus/block-nested.hcl deleted file mode 100644 index 304183a..0000000 --- a/hclwrite/fuzz/config/corpus/block-nested.hcl +++ /dev/null @@ -1,5 +0,0 @@ -block { - another_block { - foo = bar - } -} diff --git a/hclwrite/fuzz/config/corpus/complex.hcl b/hclwrite/fuzz/config/corpus/complex.hcl deleted file mode 100644 index 00a4a27..0000000 --- a/hclwrite/fuzz/config/corpus/complex.hcl +++ /dev/null @@ -1 +0,0 @@ -a = foo.bar[1].baz["foo"].pizza diff --git a/hclwrite/fuzz/config/corpus/empty.hcl b/hclwrite/fuzz/config/corpus/empty.hcl deleted file mode 100644 index e69de29..0000000 --- a/hclwrite/fuzz/config/corpus/empty.hcl +++ /dev/null diff --git a/hclwrite/fuzz/config/corpus/escape-dollar.hcl b/hclwrite/fuzz/config/corpus/escape-dollar.hcl deleted file mode 100644 index 01811cd..0000000 --- a/hclwrite/fuzz/config/corpus/escape-dollar.hcl +++ /dev/null @@ -1 +0,0 @@ -a = "hi $${var.foo}" diff --git a/hclwrite/fuzz/config/corpus/escape-newline.hcl b/hclwrite/fuzz/config/corpus/escape-newline.hcl deleted file mode 100644 index 2055548..0000000 --- a/hclwrite/fuzz/config/corpus/escape-newline.hcl +++ /dev/null @@ -1 +0,0 @@ -a = "bar\nbaz" diff --git a/hclwrite/fuzz/config/corpus/function-call-tmpl.hcl b/hclwrite/fuzz/config/corpus/function-call-tmpl.hcl deleted file mode 100644 index f641c7a..0000000 --- a/hclwrite/fuzz/config/corpus/function-call-tmpl.hcl +++ /dev/null @@ -1 +0,0 @@ -a = "b ${title(var.name)} diff --git a/hclwrite/fuzz/config/corpus/function-call.hcl b/hclwrite/fuzz/config/corpus/function-call.hcl deleted file mode 100644 index f3cafb2..0000000 --- a/hclwrite/fuzz/config/corpus/function-call.hcl +++ /dev/null @@ -1 +0,0 @@ -a = title(var.name) diff --git a/hclwrite/fuzz/config/corpus/hash-comment.hcl b/hclwrite/fuzz/config/corpus/hash-comment.hcl deleted file mode 100644 index 9d18bcb..0000000 --- a/hclwrite/fuzz/config/corpus/hash-comment.hcl +++ /dev/null @@ -1 +0,0 @@ -# another comment diff --git a/hclwrite/fuzz/config/corpus/index.hcl b/hclwrite/fuzz/config/corpus/index.hcl deleted file mode 100644 index a22dd44..0000000 --- a/hclwrite/fuzz/config/corpus/index.hcl +++ /dev/null @@ -1 +0,0 @@ -a = foo[1] diff --git a/hclwrite/fuzz/config/corpus/int-tmpl.hcl b/hclwrite/fuzz/config/corpus/int-tmpl.hcl deleted file mode 100644 index 57e94d3..0000000 --- a/hclwrite/fuzz/config/corpus/int-tmpl.hcl +++ /dev/null @@ -1 +0,0 @@ -a = "foo ${42}" diff --git a/hclwrite/fuzz/config/corpus/int.hcl b/hclwrite/fuzz/config/corpus/int.hcl deleted file mode 100644 index aec1027..0000000 --- a/hclwrite/fuzz/config/corpus/int.hcl +++ /dev/null @@ -1 +0,0 @@ -a = 42 diff --git a/hclwrite/fuzz/config/corpus/just-interp.hcl b/hclwrite/fuzz/config/corpus/just-interp.hcl deleted file mode 100644 index 018d5ed..0000000 --- a/hclwrite/fuzz/config/corpus/just-interp.hcl +++ /dev/null @@ -1 +0,0 @@ -a = "${var.bar}" diff --git a/hclwrite/fuzz/config/corpus/literal.hcl b/hclwrite/fuzz/config/corpus/literal.hcl deleted file mode 100644 index 5ae5461..0000000 --- a/hclwrite/fuzz/config/corpus/literal.hcl +++ /dev/null @@ -1 +0,0 @@ -a = foo diff --git a/hclwrite/fuzz/config/corpus/lots-of-comments.hcl b/hclwrite/fuzz/config/corpus/lots-of-comments.hcl deleted file mode 100644 index 511f085..0000000 --- a/hclwrite/fuzz/config/corpus/lots-of-comments.hcl +++ /dev/null @@ -1,14 +0,0 @@ -// comment -block { - // another comment - another_block { # comment - // comment - foo = bar - } - - /* commented out block - blah { - bar = foo - } - */ -} diff --git a/hclwrite/fuzz/config/corpus/slash-comment.hcl b/hclwrite/fuzz/config/corpus/slash-comment.hcl deleted file mode 100644 index fef83a9..0000000 --- a/hclwrite/fuzz/config/corpus/slash-comment.hcl +++ /dev/null @@ -1 +0,0 @@ -// comment diff --git a/hclwrite/fuzz/config/corpus/splat-attr.hcl b/hclwrite/fuzz/config/corpus/splat-attr.hcl deleted file mode 100644 index 38cfe14..0000000 --- a/hclwrite/fuzz/config/corpus/splat-attr.hcl +++ /dev/null @@ -1 +0,0 @@ -a = foo.bar.*.baz diff --git a/hclwrite/fuzz/config/corpus/splat-dot-full.hcl b/hclwrite/fuzz/config/corpus/splat-dot-full.hcl deleted file mode 100644 index 22e8eb0..0000000 --- a/hclwrite/fuzz/config/corpus/splat-dot-full.hcl +++ /dev/null @@ -1 +0,0 @@ -a = foo.bar.* diff --git a/hclwrite/fuzz/config/corpus/splat-full.hcl b/hclwrite/fuzz/config/corpus/splat-full.hcl deleted file mode 100644 index 4441191..0000000 --- a/hclwrite/fuzz/config/corpus/splat-full.hcl +++ /dev/null @@ -1 +0,0 @@ -a = foo.bar[*].baz diff --git a/hclwrite/fuzz/config/corpus/traversal-dot-index-terminal.hcl b/hclwrite/fuzz/config/corpus/traversal-dot-index-terminal.hcl deleted file mode 100644 index 3f3a306..0000000 --- a/hclwrite/fuzz/config/corpus/traversal-dot-index-terminal.hcl +++ /dev/null @@ -1 +0,0 @@ -a = foo.bar.0 diff --git a/hclwrite/fuzz/config/corpus/traversal-dot-index.hcl b/hclwrite/fuzz/config/corpus/traversal-dot-index.hcl deleted file mode 100644 index 31cbf8b..0000000 --- a/hclwrite/fuzz/config/corpus/traversal-dot-index.hcl +++ /dev/null @@ -1 +0,0 @@ -a = foo.bar.4.baz diff --git a/hclwrite/fuzz/config/corpus/traversal-index.hcl b/hclwrite/fuzz/config/corpus/traversal-index.hcl deleted file mode 100644 index 5523c37..0000000 --- a/hclwrite/fuzz/config/corpus/traversal-index.hcl +++ /dev/null @@ -1 +0,0 @@ -a = foo.bar[4].baz diff --git a/hclwrite/fuzz/config/corpus/utf8.hcl b/hclwrite/fuzz/config/corpus/utf8.hcl deleted file mode 100644 index ffad4b0..0000000 --- a/hclwrite/fuzz/config/corpus/utf8.hcl +++ /dev/null @@ -1 +0,0 @@ -foo = "föo ${föo("föo")}" diff --git a/hclwrite/fuzz/config/corpus/var.hcl b/hclwrite/fuzz/config/corpus/var.hcl deleted file mode 100644 index 62a9b73..0000000 --- a/hclwrite/fuzz/config/corpus/var.hcl +++ /dev/null @@ -1 +0,0 @@ -a = var.bar diff --git a/hclwrite/fuzz/config/fuzz.go b/hclwrite/fuzz/config/fuzz.go deleted file mode 100644 index ea66e67..0000000 --- a/hclwrite/fuzz/config/fuzz.go +++ /dev/null @@ -1,24 +0,0 @@ -package fuzzconfig - -import ( - "io/ioutil" - - "github.com/hashicorp/hcl/v2" - "github.com/hashicorp/hcl/v2/hclwrite" -) - -func Fuzz(data []byte) int { - file, diags := hclwrite.ParseConfig(data, "<fuzz-conf>", hcl.Pos{Line: 1, Column: 1}) - - if diags.HasErrors() { - return 0 - } - - _, err := file.WriteTo(ioutil.Discard) - - if err != nil { - return 0 - } - - return 1 -} diff --git a/hclwrite/fuzz/fuzz_test.go b/hclwrite/fuzz/fuzz_test.go new file mode 100644 index 0000000..fa29af9 --- /dev/null +++ b/hclwrite/fuzz/fuzz_test.go @@ -0,0 +1,29 @@ +package fuzzhclwrite + +import ( + "io/ioutil" + "testing" + + "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/hcl/v2/hclwrite" +) + +func FuzzParseConfig(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + file, diags := hclwrite.ParseConfig(data, "<fuzz-conf>", hcl.Pos{Line: 1, Column: 1}) + + if diags.HasErrors() { + t.Logf("Error when parsing JSON %v", data) + for _, diag := range diags { + t.Logf("- %s", diag.Error()) + } + return + } + + _, err := file.WriteTo(ioutil.Discard) + + if err != nil { + t.Fatalf("error writing to file: %s", err) + } + }) +} diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/attr-expr.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/attr-expr.hcl new file mode 100644 index 0000000..7860981 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/attr-expr.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo = upper(bar + baz[1])\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/attr-literal.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/attr-literal.hcl new file mode 100644 index 0000000..e4374f5 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/attr-literal.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo = \"bar\"\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/attr.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/attr.hcl new file mode 100644 index 0000000..971121a --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/attr.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = foo.bar\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-attrs.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-attrs.hcl new file mode 100644 index 0000000..5751d05 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-attrs.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("block {\n foo = true\n}\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-comment.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-comment.hcl new file mode 100644 index 0000000..161f06d --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-comment.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("/* multi\n line\n comment\n*/\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-empty.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-empty.hcl new file mode 100644 index 0000000..ef0e91f --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-empty.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("block {\n}\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-nested.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-nested.hcl new file mode 100644 index 0000000..0c2ed01 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-nested.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("block {\n another_block {\n foo = bar\n }\n}\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/complex.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/complex.hcl new file mode 100644 index 0000000..c3e0449 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/complex.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = foo.bar[1].baz[\"foo\"].pizza\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/empty.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/empty.hcl new file mode 100644 index 0000000..e0f2da2 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/empty.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/escape-dollar.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/escape-dollar.hcl new file mode 100644 index 0000000..ac62d24 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/escape-dollar.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = \"hi $${var.foo}\"\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/escape-newline.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/escape-newline.hcl new file mode 100644 index 0000000..eb682b4 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/escape-newline.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = \"bar\\nbaz\"\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/function-call-tmpl.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/function-call-tmpl.hcl new file mode 100644 index 0000000..fa9aa34 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/function-call-tmpl.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = \"b ${title(var.name)}\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/function-call.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/function-call.hcl new file mode 100644 index 0000000..3c75495 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/function-call.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = title(var.name)\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/hash-comment.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/hash-comment.hcl new file mode 100644 index 0000000..842b825 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/hash-comment.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("# another comment\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/index.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/index.hcl new file mode 100644 index 0000000..9ce6d49 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/index.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = foo[1]\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/int-tmpl.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/int-tmpl.hcl new file mode 100644 index 0000000..376fa2d --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/int-tmpl.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = \"foo ${42}\"\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/int.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/int.hcl new file mode 100644 index 0000000..fc0ec13 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/int.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = 42\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/just-interp.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/just-interp.hcl new file mode 100644 index 0000000..e510886 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/just-interp.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = \"${var.bar}\"\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/literal.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/literal.hcl new file mode 100644 index 0000000..ef57c89 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/literal.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = foo\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/lots-of-comments.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/lots-of-comments.hcl new file mode 100644 index 0000000..d96aecd --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/lots-of-comments.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("// comment\nblock {\n // another comment\n another_block { # comment\n // comment\n foo = bar\n }\n\n /* commented out block\n blah {\n bar = foo\n }\n */\n}\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/slash-comment.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/slash-comment.hcl new file mode 100644 index 0000000..64a7a2d --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/slash-comment.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("// comment\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/splat-attr.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/splat-attr.hcl new file mode 100644 index 0000000..3a94d66 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/splat-attr.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = foo.bar.*.baz\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/splat-dot-full.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/splat-dot-full.hcl new file mode 100644 index 0000000..60572d0 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/splat-dot-full.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = foo.bar.*\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/splat-full.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/splat-full.hcl new file mode 100644 index 0000000..12631e7 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/splat-full.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = foo.bar[*].baz\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/traversal-dot-index-terminal.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/traversal-dot-index-terminal.hcl new file mode 100644 index 0000000..39114da --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/traversal-dot-index-terminal.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = foo.bar.0\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/traversal-dot-index.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/traversal-dot-index.hcl new file mode 100644 index 0000000..beff5c4 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/traversal-dot-index.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = foo.bar.4.baz\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/traversal-index.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/traversal-index.hcl new file mode 100644 index 0000000..c1fc7c5 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/traversal-index.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = foo.bar[4].baz\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/utf8.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/utf8.hcl new file mode 100644 index 0000000..85c4a70 --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/utf8.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("foo = \"föo ${föo(\"föo\")}\"\n")
\ No newline at end of file diff --git a/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/var.hcl b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/var.hcl new file mode 100644 index 0000000..a9246bb --- /dev/null +++ b/hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/var.hcl @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("a = var.bar\n")
\ No newline at end of file diff --git a/json/fuzz/README.md b/json/fuzz/README.md index b4d7fd1..7fd0107 100644 --- a/json/fuzz/README.md +++ b/json/fuzz/README.md @@ -1,82 +1,59 @@ # JSON syntax fuzzing utilities -This directory contains helper functions and corpuses that can be used to -fuzz-test the HCL JSON parser using [go-fuzz](https://github.com/dvyukov/go-fuzz). +This directory contains helper functions and corpora that can be used to +fuzz-test the HCL JSON parser using Go's native fuzz testing capabilities. -## Work directory +Please see https://go.dev/doc/fuzz/ for more information on fuzzing. -`go-fuzz` needs a working directory where it can keep state as it works. This -should ideally be in a ramdisk for efficiency, and should probably _not_ be on -an SSD to avoid thrashing it. Here's how to create a ramdisk: +## Prerequisites +* Go 1.18 -### macOS - -``` -$ SIZE_IN_MB=1024 -$ DEVICE=`hdiutil attach -nobrowse -nomount ram://$(($SIZE_IN_MB*2048))` -$ diskutil erasevolume HFS+ RamDisk $DEVICE -$ export RAMDISK=/Volumes/RamDisk -``` +## Running the fuzzer -### Linux +Each exported function in the `json` package has a corresponding fuzz test. +These can be run one at a time via `go test`: ``` -$ mkdir /mnt/ramdisk -$ mount -t tmpfs -o size=1024M tmpfs /mnt/ramdisk -$ export RAMDISK=/mnt/ramdisk +$ cd fuzz +$ go test -fuzz FuzzParse ``` -## Running the fuzzer +This command will exit only when a crasher is found (see "Understanding the +result" below). + +## Seed corpus -Next, install `go-fuzz` and its build tool in your `GOPATH`: +The seed corpus for each fuzz test function is stored in the corresponding +directory under `json/fuzz/testdata/fuzz`. For example: ``` -$ make tools FUZZ_WORK_DIR=$RAMDISK +$ ls json/fuzz/testdata/fuzz/FuzzParse +attr-expr.hcl.json +attr-literal.hcl.json +block-attrs.hcl.json +... ``` -Now you can fuzz the parser: +Additional seed inputs can be added to this corpus. Each file must be in the Go 1.18 corpus file format. Files can be converted to this format using the `file2fuzz` tool. To install it: ``` -$ make fuzz-config FUZZ_WORK_DIR=$RAMDISK/json-fuzz-config +$ go install golang.org/x/tools/cmd/file2fuzz@latest +$ file2fuzz -help ``` -~> Note: `go-fuzz` does not interact well with `goenv`. If you encounter build -errors where the package `go.fuzz.main` could not be found, you may need to use -a machine with a direct installation of Go. - ## Understanding the result A small number of subdirectories will be created in the work directory. If you let `go-fuzz` run for a few minutes (the more minutes the better) it -may detect "crashers", which are inputs that caused the parser to panic. Details -about these are written to `$FUZZ_WORK_DIR/crashers`: +may detect "crashers", which are inputs that caused the parser to panic. +These are written to `json/fuzz/testdata/fuzz/<fuzz test name>/`: ``` -$ ls /tmp/hcl2-fuzz-config/crashers -7f5e9ec80c89da14b8b0b238ec88969f658f5a2d -7f5e9ec80c89da14b8b0b238ec88969f658f5a2d.output -7f5e9ec80c89da14b8b0b238ec88969f658f5a2d.quoted +$ ls json/fuzz/testdata/fuzz/FuzzParseTemplate +582528ddfad69eb57775199a43e0f9fd5c94bba343ce7bb6724d4ebafe311ed4 ``` -The base file above (with no extension) is the input that caused a crash. The -`.output` file contains the panic stack trace, which you can use as a clue to -figure out what caused the crash. - A good first step to fixing a detected crasher is to copy the failing input -into one of the unit tests in the `hcl/json` package and see it crash there -too. After that, it's easy to re-run the test as you try to fix it. The -file with the `.quoted` extension contains a form of the input that is quoted -in Go syntax for easy copy-paste into a test case, even if the input contains -non-printable characters or other inconvenient symbols. - -## Rebuilding for new Upstream Code - -An archive file is created for `go-fuzz` to use on the first run of each -of the above, as a `.zip` file created in this directory. If upstream code -is changed these will need to be deleted to cause them to be rebuilt with -the latest code: - -``` -$ make clean -``` +into one of the unit tests in the `json` package and see it crash there +too. After that, it's easy to re-run the test as you try to fix it. diff --git a/json/fuzz/config/corpus/attr-expr.hcl.json b/json/fuzz/config/corpus/attr-expr.hcl.json deleted file mode 100644 index fa9e852..0000000 --- a/json/fuzz/config/corpus/attr-expr.hcl.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "foo": "${upper(bar + baz[1])}" -} diff --git a/json/fuzz/config/corpus/attr-literal.hcl.json b/json/fuzz/config/corpus/attr-literal.hcl.json deleted file mode 100644 index e63d37b..0000000 --- a/json/fuzz/config/corpus/attr-literal.hcl.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "foo": "bar" -} diff --git a/json/fuzz/config/corpus/block-attrs.hcl.json b/json/fuzz/config/corpus/block-attrs.hcl.json deleted file mode 100644 index 4130811..0000000 --- a/json/fuzz/config/corpus/block-attrs.hcl.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "block": { - "foo": true - } -} diff --git a/json/fuzz/config/corpus/block-empty.json b/json/fuzz/config/corpus/block-empty.json deleted file mode 100644 index 6974555..0000000 --- a/json/fuzz/config/corpus/block-empty.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "block": {} -} diff --git a/json/fuzz/config/corpus/block-nested.hcl.json b/json/fuzz/config/corpus/block-nested.hcl.json deleted file mode 100644 index 9d964e0..0000000 --- a/json/fuzz/config/corpus/block-nested.hcl.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "block": { - "another_block": { - "foo": "bar" - } - } -} diff --git a/json/fuzz/config/corpus/empty.hcl.json b/json/fuzz/config/corpus/empty.hcl.json deleted file mode 100644 index 0967ef4..0000000 --- a/json/fuzz/config/corpus/empty.hcl.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/json/fuzz/config/corpus/list-empty.json b/json/fuzz/config/corpus/list-empty.json deleted file mode 100644 index a8471f7..0000000 --- a/json/fuzz/config/corpus/list-empty.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "hello": [] -} diff --git a/json/fuzz/config/corpus/list-nested.json b/json/fuzz/config/corpus/list-nested.json deleted file mode 100644 index 27bdf4f..0000000 --- a/json/fuzz/config/corpus/list-nested.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "hello": [[]] -} diff --git a/json/fuzz/config/corpus/list-values.json b/json/fuzz/config/corpus/list-values.json deleted file mode 100644 index 6def6cf..0000000 --- a/json/fuzz/config/corpus/list-values.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "hello": [ - "hello", - true, - 1.2 - ] -} diff --git a/json/fuzz/config/corpus/number-big.hcl.json b/json/fuzz/config/corpus/number-big.hcl.json deleted file mode 100644 index 8360c69..0000000 --- a/json/fuzz/config/corpus/number-big.hcl.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "foo": 1.234234e30 -} diff --git a/json/fuzz/config/corpus/number-int.hcl.json b/json/fuzz/config/corpus/number-int.hcl.json deleted file mode 100644 index bab9613..0000000 --- a/json/fuzz/config/corpus/number-int.hcl.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "foo": 1024 -} diff --git a/json/fuzz/config/corpus/utf8.hcl.json b/json/fuzz/config/corpus/utf8.hcl.json deleted file mode 100644 index 55afd36..0000000 --- a/json/fuzz/config/corpus/utf8.hcl.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "foo": "föo ${föo(\"föo\")}" -} diff --git a/json/fuzz/config/fuzz.go b/json/fuzz/config/fuzz.go deleted file mode 100644 index aa6214e..0000000 --- a/json/fuzz/config/fuzz.go +++ /dev/null @@ -1,15 +0,0 @@ -package fuzzconfig - -import ( - "github.com/hashicorp/hcl/v2/json" -) - -func Fuzz(data []byte) int { - _, diags := json.Parse(data, "<fuzz-conf>") - - if diags.HasErrors() { - return 0 - } - - return 1 -} diff --git a/json/fuzz/fuzz_test.go b/json/fuzz/fuzz_test.go new file mode 100644 index 0000000..f77c96b --- /dev/null +++ b/json/fuzz/fuzz_test.go @@ -0,0 +1,20 @@ +package fuzzjson + +import ( + "testing" + + "github.com/hashicorp/hcl/v2/json" +) + +func FuzzParse(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + _, diags := json.Parse(data, "<fuzz-conf>") + + if diags.HasErrors() { + t.Logf("Error when parsing JSON %v", data) + for _, diag := range diags { + t.Logf("- %s", diag.Error()) + } + } + }) +} diff --git a/json/fuzz/testdata/fuzz/FuzzParse/attr-expr.hcl.json b/json/fuzz/testdata/fuzz/FuzzParse/attr-expr.hcl.json new file mode 100644 index 0000000..8620bcd --- /dev/null +++ b/json/fuzz/testdata/fuzz/FuzzParse/attr-expr.hcl.json @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("{\n \"foo\": \"${upper(bar + baz[1])}\"\n}\n")
\ No newline at end of file diff --git a/json/fuzz/testdata/fuzz/FuzzParse/attr-literal.hcl.json b/json/fuzz/testdata/fuzz/FuzzParse/attr-literal.hcl.json new file mode 100644 index 0000000..32e599d --- /dev/null +++ b/json/fuzz/testdata/fuzz/FuzzParse/attr-literal.hcl.json @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("{\n \"foo\": \"bar\"\n}\n")
\ No newline at end of file diff --git a/json/fuzz/testdata/fuzz/FuzzParse/block-attrs.hcl.json b/json/fuzz/testdata/fuzz/FuzzParse/block-attrs.hcl.json new file mode 100644 index 0000000..45ec09f --- /dev/null +++ b/json/fuzz/testdata/fuzz/FuzzParse/block-attrs.hcl.json @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("{\n \"block\": {\n \"foo\": true\n }\n}\n")
\ No newline at end of file diff --git a/json/fuzz/testdata/fuzz/FuzzParse/block-empty.json b/json/fuzz/testdata/fuzz/FuzzParse/block-empty.json new file mode 100644 index 0000000..88d7816 --- /dev/null +++ b/json/fuzz/testdata/fuzz/FuzzParse/block-empty.json @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("{\n \"block\": {}\n}\n")
\ No newline at end of file diff --git a/json/fuzz/testdata/fuzz/FuzzParse/block-nested.hcl.json b/json/fuzz/testdata/fuzz/FuzzParse/block-nested.hcl.json new file mode 100644 index 0000000..276096a --- /dev/null +++ b/json/fuzz/testdata/fuzz/FuzzParse/block-nested.hcl.json @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("{\n \"block\": {\n \"another_block\": {\n \"foo\": \"bar\"\n }\n }\n}\n")
\ No newline at end of file diff --git a/json/fuzz/testdata/fuzz/FuzzParse/empty.hcl.json b/json/fuzz/testdata/fuzz/FuzzParse/empty.hcl.json new file mode 100644 index 0000000..fbe4fab --- /dev/null +++ b/json/fuzz/testdata/fuzz/FuzzParse/empty.hcl.json @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("{}\n")
\ No newline at end of file diff --git a/json/fuzz/testdata/fuzz/FuzzParse/list-empty.json b/json/fuzz/testdata/fuzz/FuzzParse/list-empty.json new file mode 100644 index 0000000..ad1b075 --- /dev/null +++ b/json/fuzz/testdata/fuzz/FuzzParse/list-empty.json @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("{\n \"hello\": []\n}\n")
\ No newline at end of file diff --git a/json/fuzz/testdata/fuzz/FuzzParse/list-nested.json b/json/fuzz/testdata/fuzz/FuzzParse/list-nested.json new file mode 100644 index 0000000..fb2e779 --- /dev/null +++ b/json/fuzz/testdata/fuzz/FuzzParse/list-nested.json @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("{\n \"hello\": [[]]\n}\n")
\ No newline at end of file diff --git a/json/fuzz/testdata/fuzz/FuzzParse/list-values.json b/json/fuzz/testdata/fuzz/FuzzParse/list-values.json new file mode 100644 index 0000000..8b2d4e9 --- /dev/null +++ b/json/fuzz/testdata/fuzz/FuzzParse/list-values.json @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("{\n \"hello\": [\n \"hello\",\n true,\n 1.2\n ]\n}\n")
\ No newline at end of file diff --git a/json/fuzz/testdata/fuzz/FuzzParse/number-big.hcl.json b/json/fuzz/testdata/fuzz/FuzzParse/number-big.hcl.json new file mode 100644 index 0000000..7b59d7d --- /dev/null +++ b/json/fuzz/testdata/fuzz/FuzzParse/number-big.hcl.json @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("{\n \"foo\": 1.234234e30\n}\n")
\ No newline at end of file diff --git a/json/fuzz/testdata/fuzz/FuzzParse/number-int.hcl.json b/json/fuzz/testdata/fuzz/FuzzParse/number-int.hcl.json new file mode 100644 index 0000000..0a6f064 --- /dev/null +++ b/json/fuzz/testdata/fuzz/FuzzParse/number-int.hcl.json @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("{\n \"foo\": 1024\n}\n")
\ No newline at end of file diff --git a/json/fuzz/testdata/fuzz/FuzzParse/utf8.hcl.json b/json/fuzz/testdata/fuzz/FuzzParse/utf8.hcl.json new file mode 100644 index 0000000..b20b2c6 --- /dev/null +++ b/json/fuzz/testdata/fuzz/FuzzParse/utf8.hcl.json @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("{\n \"foo\": \"föo ${föo(\\\"föo\\\")}\"\n}\n")
\ No newline at end of file |
