summaryrefslogtreecommitdiff
path: root/hclsyntax/fuzz
diff options
context:
space:
mode:
authorMartin Atkins <mart@degeneration.co.uk>2019-09-09 16:08:19 -0700
committerMartin Atkins <mart@degeneration.co.uk>2019-09-09 16:08:19 -0700
commit6c4344623b6ac528a57f9b80e4622acfab2fde40 (patch)
tree83031084d3ab54abbe40e3fd749e439c8b28e9d1 /hclsyntax/fuzz
parent0f5ab3bd563c111077917020c0cbc8c211e1bff3 (diff)
Unfold the "hcl" directory up into the root
The main HCL package is more visible this way, and so it's easier than having to pick it out from dozens of other package directories.
Diffstat (limited to 'hclsyntax/fuzz')
-rw-r--r--hclsyntax/fuzz/.gitignore1
-rw-r--r--hclsyntax/fuzz/Makefile28
-rw-r--r--hclsyntax/fuzz/README.md60
-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/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/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
36 files changed, 187 insertions, 0 deletions
diff --git a/hclsyntax/fuzz/.gitignore b/hclsyntax/fuzz/.gitignore
new file mode 100644
index 0000000..9490851
--- /dev/null
+++ b/hclsyntax/fuzz/.gitignore
@@ -0,0 +1 @@
+fuzz*-fuzz.zip
diff --git a/hclsyntax/fuzz/Makefile b/hclsyntax/fuzz/Makefile
new file mode 100644
index 0000000..ca44fa2
--- /dev/null
+++ b/hclsyntax/fuzz/Makefile
@@ -0,0 +1,28 @@
+
+ifndef FUZZ_WORK_DIR
+$(error FUZZ_WORK_DIR is not set)
+endif
+
+default:
+ @echo "See README.md for usage instructions"
+
+fuzz-config: fuzz-exec-config
+fuzz-expr: fuzz-exec-expr
+fuzz-template: fuzz-exec-template
+fuzz-traversal: fuzz-exec-traversal
+
+fuzz-exec-%: fuzz%-fuzz.zip
+ go-fuzz -bin=./fuzz$*-fuzz.zip -workdir=$(FUZZ_WORK_DIR)
+
+fuzz%-fuzz.zip: %/fuzz.go
+ go-fuzz-build github.com/hashicorp/hcl/v2/hclsyntax/fuzz/$*
+
+tools:
+ go get -u github.com/dvyukov/go-fuzz/go-fuzz
+ go get -u github.com/dvyukov/go-fuzz/go-fuzz-build
+
+clean:
+ rm fuzz*-fuzz.zip
+
+.PHONY: tools clean fuzz-config fuzz-expr fuzz-template fuzz-traversal
+.PRECIOUS: fuzzconfig-fuzz.zip fuzzexpr-fuzz.zip fuzztemplate-fuzz.zip fuzztraversal-fuzz.zip
diff --git a/hclsyntax/fuzz/README.md b/hclsyntax/fuzz/README.md
new file mode 100644
index 0000000..38960e2
--- /dev/null
+++ b/hclsyntax/fuzz/README.md
@@ -0,0 +1,60 @@
+# 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).
+
+To fuzz, first install go-fuzz and its build tool in your `GOPATH`:
+
+```
+$ make tools
+```
+
+Now you can fuzz one or all of the parsers:
+
+```
+$ make fuzz-config FUZZ_WORK_DIR=/tmp/hcl2-fuzz-config
+$ make fuzz-expr FUZZ_WORK_DIR=/tmp/hcl2-fuzz-expr
+$ make fuzz-template FUZZ_WORK_DIR=/tmp/hcl2-fuzz-template
+$ make fuzz-traversal FUZZ_WORK_DIR=/tmp/hcl2-fuzz-traversal
+```
+
+In all cases, set `FUZZ_WORK_DIR` to a directory where `go-fuzz` 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.
+
+## 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`:
+
+```
+$ ls /tmp/hcl2-fuzz-config/crashers
+7f5e9ec80c89da14b8b0b238ec88969f658f5a2d
+7f5e9ec80c89da14b8b0b238ec88969f658f5a2d.output
+7f5e9ec80c89da14b8b0b238ec88969f658f5a2d.quoted
+```
+
+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
+```
diff --git a/hclsyntax/fuzz/config/corpus/attr-expr.hcl b/hclsyntax/fuzz/config/corpus/attr-expr.hcl
new file mode 100644
index 0000000..908bbc9
--- /dev/null
+++ b/hclsyntax/fuzz/config/corpus/attr-expr.hcl
@@ -0,0 +1 @@
+foo = upper(bar + baz[1])
diff --git a/hclsyntax/fuzz/config/corpus/attr-literal.hcl b/hclsyntax/fuzz/config/corpus/attr-literal.hcl
new file mode 100644
index 0000000..5abc475
--- /dev/null
+++ b/hclsyntax/fuzz/config/corpus/attr-literal.hcl
@@ -0,0 +1 @@
+foo = "bar"
diff --git a/hclsyntax/fuzz/config/corpus/block-attrs.hcl b/hclsyntax/fuzz/config/corpus/block-attrs.hcl
new file mode 100644
index 0000000..eb529ef
--- /dev/null
+++ b/hclsyntax/fuzz/config/corpus/block-attrs.hcl
@@ -0,0 +1,3 @@
+block {
+ foo = true
+}
diff --git a/hclsyntax/fuzz/config/corpus/block-empty.hcl b/hclsyntax/fuzz/config/corpus/block-empty.hcl
new file mode 100644
index 0000000..b3b13a1
--- /dev/null
+++ b/hclsyntax/fuzz/config/corpus/block-empty.hcl
@@ -0,0 +1,2 @@
+block {
+}
diff --git a/hclsyntax/fuzz/config/corpus/block-nested.hcl b/hclsyntax/fuzz/config/corpus/block-nested.hcl
new file mode 100644
index 0000000..304183a
--- /dev/null
+++ b/hclsyntax/fuzz/config/corpus/block-nested.hcl
@@ -0,0 +1,5 @@
+block {
+ another_block {
+ foo = bar
+ }
+}
diff --git a/hclsyntax/fuzz/config/corpus/empty.hcl b/hclsyntax/fuzz/config/corpus/empty.hcl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/hclsyntax/fuzz/config/corpus/empty.hcl
diff --git a/hclsyntax/fuzz/config/corpus/utf8.hcl b/hclsyntax/fuzz/config/corpus/utf8.hcl
new file mode 100644
index 0000000..ffad4b0
--- /dev/null
+++ b/hclsyntax/fuzz/config/corpus/utf8.hcl
@@ -0,0 +1 @@
+foo = "föo ${föo("föo")}"
diff --git a/hclsyntax/fuzz/config/fuzz.go b/hclsyntax/fuzz/config/fuzz.go
new file mode 100644
index 0000000..798fa37
--- /dev/null
+++ b/hclsyntax/fuzz/config/fuzz.go
@@ -0,0 +1,16 @@
+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
new file mode 100644
index 0000000..3cc762b
--- /dev/null
+++ b/hclsyntax/fuzz/expr/corpus/empty.hcle
@@ -0,0 +1 @@
+"" \ No newline at end of file
diff --git a/hclsyntax/fuzz/expr/corpus/escape-dollar.hcle b/hclsyntax/fuzz/expr/corpus/escape-dollar.hcle
new file mode 100644
index 0000000..418c716
--- /dev/null
+++ b/hclsyntax/fuzz/expr/corpus/escape-dollar.hcle
@@ -0,0 +1 @@
+"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
new file mode 100644
index 0000000..746d917
--- /dev/null
+++ b/hclsyntax/fuzz/expr/corpus/escape-newline.hcle
@@ -0,0 +1 @@
+"bar\nbaz"
diff --git a/hclsyntax/fuzz/expr/corpus/function-call.hcle b/hclsyntax/fuzz/expr/corpus/function-call.hcle
new file mode 100644
index 0000000..23b5602
--- /dev/null
+++ b/hclsyntax/fuzz/expr/corpus/function-call.hcle
@@ -0,0 +1 @@
+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
new file mode 100644
index 0000000..f70d7bb
--- /dev/null
+++ b/hclsyntax/fuzz/expr/corpus/int.hcle
@@ -0,0 +1 @@
+42 \ No newline at end of file
diff --git a/hclsyntax/fuzz/expr/corpus/literal.hcle b/hclsyntax/fuzz/expr/corpus/literal.hcle
new file mode 100644
index 0000000..1910281
--- /dev/null
+++ b/hclsyntax/fuzz/expr/corpus/literal.hcle
@@ -0,0 +1 @@
+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
new file mode 100644
index 0000000..9fdbccd
--- /dev/null
+++ b/hclsyntax/fuzz/expr/corpus/splat-attr.hcle
@@ -0,0 +1 @@
+foo.bar.*.baz
diff --git a/hclsyntax/fuzz/expr/corpus/splat-full.hcle b/hclsyntax/fuzz/expr/corpus/splat-full.hcle
new file mode 100644
index 0000000..5c66c9f
--- /dev/null
+++ b/hclsyntax/fuzz/expr/corpus/splat-full.hcle
@@ -0,0 +1 @@
+foo.bar[*].baz
diff --git a/hclsyntax/fuzz/expr/corpus/utf8.hcle b/hclsyntax/fuzz/expr/corpus/utf8.hcle
new file mode 100644
index 0000000..c45f694
--- /dev/null
+++ b/hclsyntax/fuzz/expr/corpus/utf8.hcle
@@ -0,0 +1 @@
+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
new file mode 100644
index 0000000..a88d495
--- /dev/null
+++ b/hclsyntax/fuzz/expr/corpus/var.hcle
@@ -0,0 +1 @@
+var.bar \ No newline at end of file
diff --git a/hclsyntax/fuzz/expr/fuzz.go b/hclsyntax/fuzz/expr/fuzz.go
new file mode 100644
index 0000000..12708e8
--- /dev/null
+++ b/hclsyntax/fuzz/expr/fuzz.go
@@ -0,0 +1,16 @@
+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/template/corpus/empty.tmpl b/hclsyntax/fuzz/template/corpus/empty.tmpl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/hclsyntax/fuzz/template/corpus/empty.tmpl
diff --git a/hclsyntax/fuzz/template/corpus/escape-dollar.tmpl b/hclsyntax/fuzz/template/corpus/escape-dollar.tmpl
new file mode 100644
index 0000000..ec6ebc7
--- /dev/null
+++ b/hclsyntax/fuzz/template/corpus/escape-dollar.tmpl
@@ -0,0 +1 @@
+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
new file mode 100644
index 0000000..dc5c9fc
--- /dev/null
+++ b/hclsyntax/fuzz/template/corpus/escape-newline.tmpl
@@ -0,0 +1 @@
+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
new file mode 100644
index 0000000..b4ee261
--- /dev/null
+++ b/hclsyntax/fuzz/template/corpus/function-call.tmpl
@@ -0,0 +1 @@
+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
new file mode 100644
index 0000000..9337c90
--- /dev/null
+++ b/hclsyntax/fuzz/template/corpus/int.tmpl
@@ -0,0 +1 @@
+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
new file mode 100644
index 0000000..5c95825
--- /dev/null
+++ b/hclsyntax/fuzz/template/corpus/just-interp.tmpl
@@ -0,0 +1 @@
+${var.bar} \ No newline at end of file
diff --git a/hclsyntax/fuzz/template/corpus/literal.tmpl b/hclsyntax/fuzz/template/corpus/literal.tmpl
new file mode 100644
index 0000000..1910281
--- /dev/null
+++ b/hclsyntax/fuzz/template/corpus/literal.tmpl
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/hclsyntax/fuzz/template/corpus/utf8.tmpl b/hclsyntax/fuzz/template/corpus/utf8.tmpl
new file mode 100644
index 0000000..8d4aa44
--- /dev/null
+++ b/hclsyntax/fuzz/template/corpus/utf8.tmpl
@@ -0,0 +1 @@
+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
new file mode 100644
index 0000000..d17963c
--- /dev/null
+++ b/hclsyntax/fuzz/template/fuzz.go
@@ -0,0 +1,16 @@
+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/traversal/corpus/attr.hclt b/hclsyntax/fuzz/traversal/corpus/attr.hclt
new file mode 100644
index 0000000..4d5f975
--- /dev/null
+++ b/hclsyntax/fuzz/traversal/corpus/attr.hclt
@@ -0,0 +1 @@
+foo.bar \ No newline at end of file
diff --git a/hclsyntax/fuzz/traversal/corpus/complex.hclt b/hclsyntax/fuzz/traversal/corpus/complex.hclt
new file mode 100644
index 0000000..1eb90f0
--- /dev/null
+++ b/hclsyntax/fuzz/traversal/corpus/complex.hclt
@@ -0,0 +1 @@
+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
new file mode 100644
index 0000000..83c639a
--- /dev/null
+++ b/hclsyntax/fuzz/traversal/corpus/index.hclt
@@ -0,0 +1 @@
+foo[1] \ No newline at end of file
diff --git a/hclsyntax/fuzz/traversal/corpus/root.hclt b/hclsyntax/fuzz/traversal/corpus/root.hclt
new file mode 100644
index 0000000..1910281
--- /dev/null
+++ b/hclsyntax/fuzz/traversal/corpus/root.hclt
@@ -0,0 +1 @@
+foo \ No newline at end of file
diff --git a/hclsyntax/fuzz/traversal/fuzz.go b/hclsyntax/fuzz/traversal/fuzz.go
new file mode 100644
index 0000000..856498f
--- /dev/null
+++ b/hclsyntax/fuzz/traversal/fuzz.go
@@ -0,0 +1,16 @@
+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
+}