Merge pull request #134 from hashicorp/b-fuzz
Fix parser bugs found via fuzzing from GH-128
This commit is contained in:
commit
61f5143284
@ -269,9 +269,7 @@ func TestDecode_interface(t *testing.T) {
|
|||||||
{
|
{
|
||||||
"nested_provider_bad.hcl",
|
"nested_provider_bad.hcl",
|
||||||
true,
|
true,
|
||||||
// This is not ideal but without significant rework of the decoder
|
nil,
|
||||||
// we get a partial result back as well as an error.
|
|
||||||
map[string]interface{}{},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -334,6 +332,42 @@ func TestDecode_interface(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDecode_interfaceInline(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Value string
|
||||||
|
Err bool
|
||||||
|
Out interface{}
|
||||||
|
}{
|
||||||
|
{"t t e{{}}", true, nil},
|
||||||
|
{"t=0t d {}", true, map[string]interface{}{"t": 0}},
|
||||||
|
{"v=0E0v d{}", true, map[string]interface{}{"v": float64(0)}},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
t.Logf("Testing: %q", tc.Value)
|
||||||
|
|
||||||
|
var out interface{}
|
||||||
|
err := Decode(&out, tc.Value)
|
||||||
|
if (err != nil) != tc.Err {
|
||||||
|
t.Fatalf("Input: %q\n\nError: %s", tc.Value, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(out, tc.Out) {
|
||||||
|
t.Fatalf("Input: %q. Actual, Expected.\n\n%#v\n\n%#v", tc.Value, out, tc.Out)
|
||||||
|
}
|
||||||
|
|
||||||
|
var v interface{}
|
||||||
|
err = Unmarshal([]byte(tc.Value), &v)
|
||||||
|
if (err != nil) != tc.Err {
|
||||||
|
t.Fatalf("Input: %q\n\nError: %s", tc.Value, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(v, tc.Out) {
|
||||||
|
t.Fatalf("Input: %q. Actual, Expected.\n\n%#v\n\n%#v", tc.Value, out, tc.Out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDecode_equal(t *testing.T) {
|
func TestDecode_equal(t *testing.T) {
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
One, Two string
|
One, Two string
|
||||||
|
@ -133,6 +133,12 @@ type ObjectItem struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *ObjectItem) Pos() token.Pos {
|
func (o *ObjectItem) Pos() token.Pos {
|
||||||
|
// I'm not entirely sure what causes this, but removing this causes
|
||||||
|
// a test failure. We should investigate at some point.
|
||||||
|
if len(o.Keys) == 0 {
|
||||||
|
return token.Pos{}
|
||||||
|
}
|
||||||
|
|
||||||
return o.Keys[0].Pos()
|
return o.Keys[0].Pos()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,8 +220,19 @@ func (p *Parser) objectKey() ([]*ast.ObjectKey, error) {
|
|||||||
|
|
||||||
return keys, nil
|
return keys, nil
|
||||||
case token.LBRACE:
|
case token.LBRACE:
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// If we have no keys, then it is a syntax error. i.e. {{}} is not
|
||||||
|
// allowed.
|
||||||
|
if len(keys) == 0 {
|
||||||
|
err = &PosError{
|
||||||
|
Pos: p.tok.Pos,
|
||||||
|
Err: fmt.Errorf("expected: IDENT | STRING got: %s", p.tok.Type),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// object
|
// object
|
||||||
return keys, nil
|
return keys, err
|
||||||
case token.IDENT, token.STRING:
|
case token.IDENT, token.STRING:
|
||||||
keyCount++
|
keyCount++
|
||||||
keys = append(keys, &ast.ObjectKey{Token: p.tok})
|
keys = append(keys, &ast.ObjectKey{Token: p.tok})
|
||||||
@ -320,7 +331,7 @@ func (p *Parser) listType() (*ast.ListType, error) {
|
|||||||
// get next list item or we are at the end
|
// get next list item or we are at the end
|
||||||
// do a look-ahead for line comment
|
// do a look-ahead for line comment
|
||||||
p.scan()
|
p.scan()
|
||||||
if p.lineComment != nil {
|
if p.lineComment != nil && len(l.List) > 0 {
|
||||||
lit, ok := l.List[len(l.List)-1].(*ast.LiteralType)
|
lit, ok := l.List[len(l.List)-1].(*ast.LiteralType)
|
||||||
if ok {
|
if ok {
|
||||||
lit.LineComment = p.lineComment
|
lit.LineComment = p.lineComment
|
||||||
|
@ -332,6 +332,29 @@ func TestParse(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParse_inline(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Value string
|
||||||
|
Err bool
|
||||||
|
}{
|
||||||
|
{"t t e{{}}", true},
|
||||||
|
{"o{{}}", true},
|
||||||
|
{"t t e d N{{}}", true},
|
||||||
|
{"t t e d{{}}", true},
|
||||||
|
{"N{}N{{}}", true},
|
||||||
|
{"v\nN{{}}", true},
|
||||||
|
{"v=/\n[,", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
t.Logf("Testing: %q", tc.Value)
|
||||||
|
_, err := Parse([]byte(tc.Value))
|
||||||
|
if (err != nil) != tc.Err {
|
||||||
|
t.Fatalf("Input: %q\n\nError: %s\n\nAST: %s", tc.Value, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// equals fails the test if exp is not equal to act.
|
// equals fails the test if exp is not equal to act.
|
||||||
func equals(tb testing.TB, exp, act interface{}) {
|
func equals(tb testing.TB, exp, act interface{}) {
|
||||||
if !reflect.DeepEqual(exp, act) {
|
if !reflect.DeepEqual(exp, act) {
|
||||||
|
@ -332,6 +332,22 @@ func TestParse(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParse_inline(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Value string
|
||||||
|
Err bool
|
||||||
|
}{
|
||||||
|
{"{:{", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
_, err := Parse([]byte(tc.Value))
|
||||||
|
if (err != nil) != tc.Err {
|
||||||
|
t.Fatalf("Input: %q\n\nError: %s", tc.Value, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// equals fails the test if exp is not equal to act.
|
// equals fails the test if exp is not equal to act.
|
||||||
func equals(tb testing.TB, exp, act interface{}) {
|
func equals(tb testing.TB, exp, act interface{}) {
|
||||||
if !reflect.DeepEqual(exp, act) {
|
if !reflect.DeepEqual(exp, act) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user