summaryrefslogtreecommitdiff
path: root/json/fuzz/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'json/fuzz/README.md')
-rw-r--r--json/fuzz/README.md83
1 files changed, 30 insertions, 53 deletions
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.