Skip to content

Commit

Permalink
json: Fix panic when parsing malformed JSON
Browse files Browse the repository at this point in the history
When scanning JSON, upon encountering an invalid token, we immediately
return. Previously this return happened without inserting an EOF token.
Since other functions assume that a token sequence always ends in EOF,
this could cause a panic.

This commit adds a synthetic EOF token after the invalid token before
returning. While this does not match the real end-of-file of the source
JSON, it is marking the end of the scanned bytes, so it seems reasonable.

Fixes hashicorp#339
  • Loading branch information
alisdair committed Mar 25, 2020
1 parent cda5e9c commit b265bbd
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
17 changes: 17 additions & 0 deletions json/public_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package json

import (
"strings"
"testing"

"github.com/hashicorp/hcl/v2"
Expand Down Expand Up @@ -95,3 +96,19 @@ func TestParseTemplateUnwrap(t *testing.T) {
t.Errorf("wrong result %#v; want %#v", val, cty.True)
}
}

func TestParse_malformed(t *testing.T) {
src := `{
"http_proxy_url: "https://xxxxxx",
}`
file, diags := Parse([]byte(src), "")
if got, want := len(diags), 2; got != want {
t.Errorf("got %d diagnostics; want %d", got, want)
}
if err, want := diags.Error(), `Missing property value colon`; !strings.Contains(err, want) {
t.Errorf("diags are %q, but should contain %q", err, want)
}
if file == nil {
t.Errorf("got nil File; want actual file")
}
}
9 changes: 9 additions & 0 deletions json/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,15 @@ func scan(buf []byte, start pos) []token {
})
// If we've encountered an invalid then we might as well stop
// scanning since the parser won't proceed beyond this point.
// We insert a synthetic EOF marker here to match the expectations
// of consumers of this data structure.
p.Pos.Column++
p.Pos.Byte++
tokens = append(tokens, token{
Type: tokenEOF,
Bytes: nil,
Range: posRange(p, p),
})
return tokens
}
}
Expand Down
15 changes: 15 additions & 0 deletions json/scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,21 @@ func TestScan(t *testing.T) {
},
},
},
{
Type: tokenEOF,
Range: hcl.Range{
Start: hcl.Pos{
Byte: 1,
Line: 1,
Column: 2,
},
End: hcl.Pos{
Byte: 1,
Line: 1,
Column: 2,
},
},
},
},
},
}
Expand Down

0 comments on commit b265bbd

Please sign in to comment.