v0.1.0 initial commit
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
package toml
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func FuzzParse(f *testing.F) {
|
||||
for _, s := range []string{
|
||||
"",
|
||||
`key = "value"`,
|
||||
"[table]\nk = 1",
|
||||
"[[arr]]\nx = 1.5\n[[arr]]\nx = 2e3",
|
||||
"t = { a = 1, b = { c = [1, 2] } }",
|
||||
`s = "esc \u00E9 \t"`,
|
||||
"n = -0x10\nb = 0b101\no = 0o17",
|
||||
} {
|
||||
f.Add([]byte(s))
|
||||
}
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
p := NewParser(data)
|
||||
_, _ = p.Parse() // property: no panic, no hang
|
||||
})
|
||||
}
|
||||
|
||||
// normalize collapses the parser's dual slice representations
|
||||
// ([]map[string]any for [[headers]], []any for inline arrays) so the
|
||||
// fixpoint compares values, not construction syntax.
|
||||
func normalize(v any) any {
|
||||
switch t := v.(type) {
|
||||
case map[string]any:
|
||||
for k, vv := range t {
|
||||
t[k] = normalize(vv)
|
||||
}
|
||||
return t
|
||||
case []map[string]any:
|
||||
out := make([]any, len(t))
|
||||
for i, m := range t {
|
||||
out[i] = normalize(m)
|
||||
}
|
||||
return out
|
||||
case []any:
|
||||
for i, vv := range t {
|
||||
t[i] = normalize(vv)
|
||||
}
|
||||
return t
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func FuzzRoundTrip(f *testing.F) {
|
||||
for _, s := range []string{
|
||||
"a = 1\nb = 2.5\nc = true\nd = \"x\"",
|
||||
"[t]\nk = [1, 2, 3]",
|
||||
"[[s]]\nn = \"a\"\n[[s]]\nn = \"b\"",
|
||||
`m = { x = 1, y = { z = "q" } }`,
|
||||
`u = "日本語 \u00E9"`,
|
||||
"big = 1e100\nsmall = 1e-100",
|
||||
} {
|
||||
f.Add([]byte(s))
|
||||
}
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Encoder normalizes invalid UTF-8 to U+FFFD (WriteRune); byte-exact
|
||||
// round trip is only a property of valid input.
|
||||
if !utf8.Valid(data) {
|
||||
t.Skip()
|
||||
}
|
||||
m1, err := NewParser(data).Parse()
|
||||
if err != nil {
|
||||
t.Skip()
|
||||
}
|
||||
out, err := Marshal(m1)
|
||||
if err != nil {
|
||||
// Parser accepts values the encoder cannot represent
|
||||
// (mixed table/scalar arrays). Documented asymmetry.
|
||||
t.Skip()
|
||||
}
|
||||
m2, err := NewParser(out).Parse()
|
||||
if err != nil {
|
||||
t.Fatalf("emitted TOML failed to re-parse: %v\nemitted:\n%s", err, out)
|
||||
}
|
||||
if !reflect.DeepEqual(normalize(m1), normalize(m2)) {
|
||||
t.Fatalf("fixpoint violation:\nm1: %#v\nm2: %#v\nemitted:\n%s", m1, m2, out)
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user