summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkmoe <5575356+kmoe@users.noreply.github.com>2022-06-21 14:35:40 +0100
committerGitHub <noreply@github.com>2022-06-21 14:35:40 +0100
commit986b8816d5d38d6b71f9083d7f03ee702d85d5f7 (patch)
tree1f81f224cc9405f1bd13a30d70fcb49249a485b2
parentc3b671524ef9402b2837c2fd14a4ed115fc69772 (diff)
parentc020cb984b9deb3e9fa7593af2782ae57c7fa149 (diff)
Merge pull request #508 from hashicorp/go118fuzz
Port fuzz testing to Go 1.18 native fuzzing
-rw-r--r--.github/workflows/push.yml8
-rw-r--r--hclsyntax/fuzz/README.md87
-rw-r--r--hclsyntax/fuzz/config/corpus/attr-expr.hcl1
-rw-r--r--hclsyntax/fuzz/config/corpus/attr-literal.hcl1
-rw-r--r--hclsyntax/fuzz/config/corpus/block-attrs.hcl3
-rw-r--r--hclsyntax/fuzz/config/corpus/block-empty.hcl2
-rw-r--r--hclsyntax/fuzz/config/corpus/block-nested.hcl5
-rw-r--r--hclsyntax/fuzz/config/corpus/empty.hcl0
-rw-r--r--hclsyntax/fuzz/config/corpus/utf8.hcl1
-rw-r--r--hclsyntax/fuzz/config/fuzz.go16
-rw-r--r--hclsyntax/fuzz/expr/corpus/empty.hcle1
-rw-r--r--hclsyntax/fuzz/expr/corpus/escape-dollar.hcle1
-rw-r--r--hclsyntax/fuzz/expr/corpus/escape-newline.hcle1
-rw-r--r--hclsyntax/fuzz/expr/corpus/function-call.hcle1
-rw-r--r--hclsyntax/fuzz/expr/corpus/int.hcle1
-rw-r--r--hclsyntax/fuzz/expr/corpus/literal.hcle1
-rw-r--r--hclsyntax/fuzz/expr/corpus/splat-attr.hcle1
-rw-r--r--hclsyntax/fuzz/expr/corpus/splat-full.hcle1
-rw-r--r--hclsyntax/fuzz/expr/corpus/utf8.hcle1
-rw-r--r--hclsyntax/fuzz/expr/corpus/var.hcle1
-rw-r--r--hclsyntax/fuzz/expr/fuzz.go16
-rw-r--r--hclsyntax/fuzz/fuzz_test.go60
-rw-r--r--hclsyntax/fuzz/template/corpus/empty.tmpl0
-rw-r--r--hclsyntax/fuzz/template/corpus/escape-dollar.tmpl1
-rw-r--r--hclsyntax/fuzz/template/corpus/escape-newline.tmpl1
-rw-r--r--hclsyntax/fuzz/template/corpus/function-call.tmpl1
-rw-r--r--hclsyntax/fuzz/template/corpus/int.tmpl1
-rw-r--r--hclsyntax/fuzz/template/corpus/just-interp.tmpl1
-rw-r--r--hclsyntax/fuzz/template/corpus/literal.tmpl1
-rw-r--r--hclsyntax/fuzz/template/corpus/utf8.tmpl1
-rw-r--r--hclsyntax/fuzz/template/fuzz.go16
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/attr-expr.hcl2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/attr-literal.hcl2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/block-attrs.hcl2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/block-empty.hcl2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/block-nested.hcl2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/empty.hcl2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseConfig/utf8.hcl2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/empty.hcle2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/escape-dollar.hcle2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/escape-newline.hcle2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/function-call.hcle2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/int.hcle2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/literal.hcle2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/splat-attr.hcle2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/splat-full.hcle2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/utf8.hcle2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseExpression/var.hcle2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/empty.tmpl2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/escape-dollar.tmpl2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/escape-newline.tmpl2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/function-call.tmpl2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/int.tmpl2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/just-interp.tmpl2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/literal.tmpl2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseTemplate/utf8.tmpl2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/attr.hclt2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/complex.hclt2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/index.hclt2
-rw-r--r--hclsyntax/fuzz/testdata/fuzz/FuzzParseTraversalAbs/root.hclt2
-rw-r--r--hclsyntax/fuzz/traversal/corpus/attr.hclt1
-rw-r--r--hclsyntax/fuzz/traversal/corpus/complex.hclt1
-rw-r--r--hclsyntax/fuzz/traversal/corpus/index.hclt1
-rw-r--r--hclsyntax/fuzz/traversal/corpus/root.hclt1
-rw-r--r--hclsyntax/fuzz/traversal/fuzz.go16
-rw-r--r--hclwrite/fuzz/README.md81
-rw-r--r--hclwrite/fuzz/config/corpus/attr-expr.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/attr-literal.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/attr.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/block-attrs.hcl3
-rw-r--r--hclwrite/fuzz/config/corpus/block-comment.hcl4
-rw-r--r--hclwrite/fuzz/config/corpus/block-empty.hcl2
-rw-r--r--hclwrite/fuzz/config/corpus/block-nested.hcl5
-rw-r--r--hclwrite/fuzz/config/corpus/complex.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/empty.hcl0
-rw-r--r--hclwrite/fuzz/config/corpus/escape-dollar.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/escape-newline.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/function-call-tmpl.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/function-call.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/hash-comment.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/index.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/int-tmpl.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/int.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/just-interp.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/literal.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/lots-of-comments.hcl14
-rw-r--r--hclwrite/fuzz/config/corpus/slash-comment.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/splat-attr.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/splat-dot-full.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/splat-full.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/traversal-dot-index-terminal.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/traversal-dot-index.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/traversal-index.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/utf8.hcl1
-rw-r--r--hclwrite/fuzz/config/corpus/var.hcl1
-rw-r--r--hclwrite/fuzz/config/fuzz.go24
-rw-r--r--hclwrite/fuzz/fuzz_test.go29
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/attr-expr.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/attr-literal.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/attr.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-attrs.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-comment.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-empty.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/block-nested.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/complex.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/empty.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/escape-dollar.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/escape-newline.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/function-call-tmpl.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/function-call.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/hash-comment.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/index.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/int-tmpl.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/int.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/just-interp.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/literal.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/lots-of-comments.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/slash-comment.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/splat-attr.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/splat-dot-full.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/splat-full.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/traversal-dot-index-terminal.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/traversal-dot-index.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/traversal-index.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/utf8.hcl2
-rw-r--r--hclwrite/fuzz/testdata/fuzz/FuzzParseConfig/var.hcl2
-rw-r--r--json/fuzz/README.md83
-rw-r--r--json/fuzz/config/corpus/attr-expr.hcl.json3
-rw-r--r--json/fuzz/config/corpus/attr-literal.hcl.json3
-rw-r--r--json/fuzz/config/corpus/block-attrs.hcl.json5
-rw-r--r--json/fuzz/config/corpus/block-empty.json3
-rw-r--r--json/fuzz/config/corpus/block-nested.hcl.json7
-rw-r--r--json/fuzz/config/corpus/empty.hcl.json1
-rw-r--r--json/fuzz/config/corpus/list-empty.json3
-rw-r--r--json/fuzz/config/corpus/list-nested.json3
-rw-r--r--json/fuzz/config/corpus/list-values.json7
-rw-r--r--json/fuzz/config/corpus/number-big.hcl.json3
-rw-r--r--json/fuzz/config/corpus/number-int.hcl.json3
-rw-r--r--json/fuzz/config/corpus/utf8.hcl.json3
-rw-r--r--json/fuzz/config/fuzz.go15
-rw-r--r--json/fuzz/fuzz_test.go20
-rw-r--r--json/fuzz/testdata/fuzz/FuzzParse/attr-expr.hcl.json2
-rw-r--r--json/fuzz/testdata/fuzz/FuzzParse/attr-literal.hcl.json2
-rw-r--r--json/fuzz/testdata/fuzz/FuzzParse/block-attrs.hcl.json2
-rw-r--r--json/fuzz/testdata/fuzz/FuzzParse/block-empty.json2
-rw-r--r--json/fuzz/testdata/fuzz/FuzzParse/block-nested.hcl.json2
-rw-r--r--json/fuzz/testdata/fuzz/FuzzParse/empty.hcl.json2
-rw-r--r--json/fuzz/testdata/fuzz/FuzzParse/list-empty.json2
-rw-r--r--json/fuzz/testdata/fuzz/FuzzParse/list-nested.json2
-rw-r--r--json/fuzz/testdata/fuzz/FuzzParse/list-values.json2
-rw-r--r--json/fuzz/testdata/fuzz/FuzzParse/number-big.hcl.json2
-rw-r--r--json/fuzz/testdata/fuzz/FuzzParse/number-int.hcl.json2
-rw-r--r--json/fuzz/testdata/fuzz/FuzzParse/utf8.hcl.json2
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