Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decode: fix non-terminated array error #584

Merged
merged 2 commits into from
Sep 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ func wrapDecodeError(document []byte, de *decodeError) *DecodeError {
maxLine := errLine + len(after) - 1
lineColumnWidth := len(strconv.Itoa(maxLine))

// Write the lines of context strictly before the error.
for i := len(before) - 1; i > 0; i-- {
line := errLine - i
buf.WriteString(formatLineNumber(line, lineColumnWidth))
Expand All @@ -129,6 +130,8 @@ func wrapDecodeError(document []byte, de *decodeError) *DecodeError {
buf.WriteRune('\n')
}

// Write the document line that contains the error.

buf.WriteString(formatLineNumber(errLine, lineColumnWidth))
buf.WriteString("| ")

Expand All @@ -143,6 +146,10 @@ func wrapDecodeError(document []byte, de *decodeError) *DecodeError {
}

buf.WriteRune('\n')

// Write the line with the error message itself (so it does not have a line
// number).

buf.WriteString(strings.Repeat(" ", lineColumnWidth))
buf.WriteString("| ")

Expand All @@ -157,6 +164,8 @@ func wrapDecodeError(document []byte, de *decodeError) *DecodeError {
buf.WriteString(errMessage)
}

// Write the lines of context strictly after the error.

for i := 1; i < len(after); i++ {
buf.WriteRune('\n')
line := errLine + i
Expand Down Expand Up @@ -230,7 +239,7 @@ forward:
rest = rest[o+1:]
o = 0

case o == len(rest)-1 && o > 0:
case o == len(rest)-1:
// add last line only if it's non-empty
afterLines = append(afterLines, rest)

Expand Down
7 changes: 7 additions & 0 deletions errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@ line 5`,
6|
7| line 4`,
},
{
desc: "handle remainder of the error line when there is only one line",
doc: [3]string{`P=`, `[`, `#`},
msg: "array is incomplete",
expected: `1| P=[#
| ~ array is incomplete`,
},
}

for _, e := range examples {
Expand Down
3 changes: 2 additions & 1 deletion parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ func (p *parser) parseValArray(b []byte) (ast.Reference, []byte, error) {
// array-values =/ ws-comment-newline val ws-comment-newline [ array-sep ]
// array-sep = %x2C ; , Comma
// ws-comment-newline = *( wschar / [ comment ] newline )
arrayStart := b
b = b[1:]

parent := p.builder.Push(ast.Node{
Expand All @@ -415,7 +416,7 @@ func (p *parser) parseValArray(b []byte) (ast.Reference, []byte, error) {
}

if len(b) == 0 {
return parent, nil, newDecodeError(b, "array is incomplete")
return parent, nil, newDecodeError(arrayStart[:1], "array is incomplete")
}

if b[0] == ']' {
Expand Down
6 changes: 6 additions & 0 deletions unmarshaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1728,6 +1728,12 @@ func TestIssue579(t *testing.T) {
require.Error(t, err)
}

func TestIssue581(t *testing.T) {
var v interface{}
err := toml.Unmarshal([]byte(`P=[#`), &v)
require.Error(t, err)
}

//nolint:funlen
func TestUnmarshalDecodeErrors(t *testing.T) {
examples := []struct {
Expand Down