aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/go-logfmt/logfmt/fuzz.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/go-logfmt/logfmt/fuzz.go')
-rw-r--r--vendor/github.com/go-logfmt/logfmt/fuzz.go126
1 files changed, 126 insertions, 0 deletions
diff --git a/vendor/github.com/go-logfmt/logfmt/fuzz.go b/vendor/github.com/go-logfmt/logfmt/fuzz.go
new file mode 100644
index 0000000..6553b35
--- /dev/null
+++ b/vendor/github.com/go-logfmt/logfmt/fuzz.go
@@ -0,0 +1,126 @@
+// +build gofuzz
+
+package logfmt
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "io"
+ "reflect"
+
+ kr "github.com/kr/logfmt"
+)
+
+// Fuzz checks reserialized data matches
+func Fuzz(data []byte) int {
+ parsed, err := parse(data)
+ if err != nil {
+ return 0
+ }
+ var w1 bytes.Buffer
+ if err = write(parsed, &w1); err != nil {
+ panic(err)
+ }
+ parsed, err = parse(w1.Bytes())
+ if err != nil {
+ panic(err)
+ }
+ var w2 bytes.Buffer
+ if err = write(parsed, &w2); err != nil {
+ panic(err)
+ }
+ if !bytes.Equal(w1.Bytes(), w2.Bytes()) {
+ panic(fmt.Sprintf("reserialized data does not match:\n%q\n%q\n", w1.Bytes(), w2.Bytes()))
+ }
+ return 1
+}
+
+// FuzzVsKR checks go-logfmt/logfmt against kr/logfmt
+func FuzzVsKR(data []byte) int {
+ parsed, err := parse(data)
+ parsedKR, errKR := parseKR(data)
+
+ // github.com/go-logfmt/logfmt is a stricter parser. It returns errors for
+ // more inputs than github.com/kr/logfmt. Ignore any inputs that have a
+ // stict error.
+ if err != nil {
+ return 0
+ }
+
+ // Fail if the more forgiving parser finds an error not found by the
+ // stricter parser.
+ if errKR != nil {
+ panic(fmt.Sprintf("unmatched error: %v", errKR))
+ }
+
+ if !reflect.DeepEqual(parsed, parsedKR) {
+ panic(fmt.Sprintf("parsers disagree:\n%+v\n%+v\n", parsed, parsedKR))
+ }
+ return 1
+}
+
+type kv struct {
+ k, v []byte
+}
+
+func parse(data []byte) ([][]kv, error) {
+ var got [][]kv
+ dec := NewDecoder(bytes.NewReader(data))
+ for dec.ScanRecord() {
+ var kvs []kv
+ for dec.ScanKeyval() {
+ kvs = append(kvs, kv{dec.Key(), dec.Value()})
+ }
+ got = append(got, kvs)
+ }
+ return got, dec.Err()
+}
+
+func parseKR(data []byte) ([][]kv, error) {
+ var (
+ s = bufio.NewScanner(bytes.NewReader(data))
+ err error
+ h saveHandler
+ got [][]kv
+ )
+ for err == nil && s.Scan() {
+ h.kvs = nil
+ err = kr.Unmarshal(s.Bytes(), &h)
+ got = append(got, h.kvs)
+ }
+ if err == nil {
+ err = s.Err()
+ }
+ return got, err
+}
+
+type saveHandler struct {
+ kvs []kv
+}
+
+func (h *saveHandler) HandleLogfmt(key, val []byte) error {
+ if len(key) == 0 {
+ key = nil
+ }
+ if len(val) == 0 {
+ val = nil
+ }
+ h.kvs = append(h.kvs, kv{key, val})
+ return nil
+}
+
+func write(recs [][]kv, w io.Writer) error {
+ enc := NewEncoder(w)
+ for _, rec := range recs {
+ for _, f := range rec {
+ if err := enc.EncodeKeyval(f.k, f.v); err != nil {
+ return err
+ }
+ }
+ if err := enc.EndRecord(); err != nil {
+ return err
+ }
+ }
+ return nil
+}
nihil fit ex nihilo