@@ -2,7 +2,6 @@ package toml
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/pelletier/go-toml/v2/internal/ast"
|
||||
@@ -77,7 +76,6 @@ func (p *parser) parseNewline(b []byte) ([]byte, error) {
|
||||
|
||||
if b[0] == '\r' {
|
||||
_, rest, err := scanWindowsNewline(b)
|
||||
|
||||
return rest, err
|
||||
}
|
||||
|
||||
@@ -206,6 +204,10 @@ func (p *parser) parseKeyval(b []byte) (ast.Reference, []byte, error) {
|
||||
|
||||
b = p.parseWhitespace(b)
|
||||
|
||||
if len(b) == 0 {
|
||||
return ast.Reference{}, nil, newDecodeError(b, "expected = after a key, but the document ends there")
|
||||
}
|
||||
|
||||
b, err = expect('=', b)
|
||||
if err != nil {
|
||||
return ast.Reference{}, nil, err
|
||||
@@ -304,6 +306,7 @@ func atmost(b []byte, n int) []byte {
|
||||
if n >= len(b) {
|
||||
return b
|
||||
}
|
||||
|
||||
return b[:n]
|
||||
}
|
||||
|
||||
@@ -397,8 +400,7 @@ func (p *parser) parseValArray(b []byte) (ast.Reference, []byte, error) {
|
||||
}
|
||||
|
||||
if len(b) == 0 {
|
||||
//nolint:godox
|
||||
return parent, nil, unexpectedCharacter{b: b} // TODO: should be unexpected EOF
|
||||
return parent, nil, newDecodeError(b, "array is incomplete")
|
||||
}
|
||||
|
||||
if b[0] == ']' {
|
||||
@@ -562,7 +564,7 @@ func (p *parser) parseMultilineBasicString(b []byte) ([]byte, []byte, error) {
|
||||
case 't':
|
||||
builder.WriteByte('\t')
|
||||
case 'u':
|
||||
x, err := hexToString(token[i+3:len(token)-3], 4)
|
||||
x, err := hexToString(atmost(token[i+1:], 4), 4)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -570,7 +572,7 @@ func (p *parser) parseMultilineBasicString(b []byte) ([]byte, []byte, error) {
|
||||
builder.WriteString(x)
|
||||
i += 4
|
||||
case 'U':
|
||||
x, err := hexToString(token[i+3:len(token)-3], 8)
|
||||
x, err := hexToString(atmost(token[i+1:], 8), 8)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -610,12 +612,7 @@ func (p *parser) parseKey(b []byte) (ast.Reference, []byte, error) {
|
||||
for {
|
||||
b = p.parseWhitespace(b)
|
||||
if len(b) > 0 && b[0] == '.' {
|
||||
b, err = expect('.', b)
|
||||
if err != nil {
|
||||
return ref, nil, err
|
||||
}
|
||||
|
||||
b = p.parseWhitespace(b)
|
||||
b = p.parseWhitespace(b[1:])
|
||||
|
||||
key, b, err = p.parseSimpleKey(b)
|
||||
if err != nil {
|
||||
@@ -639,8 +636,7 @@ func (p *parser) parseSimpleKey(b []byte) (key, rest []byte, err error) {
|
||||
// unquoted-key = 1*( ALPHA / DIGIT / %x2D / %x5F ) ; A-Z / a-z / 0-9 / - / _
|
||||
// quoted-key = basic-string / literal-string
|
||||
if len(b) == 0 {
|
||||
//nolint:godox
|
||||
return nil, nil, unexpectedCharacter{b: b} // TODO: should be unexpected EOF
|
||||
return nil, nil, newDecodeError(b, "key is incomplete")
|
||||
}
|
||||
|
||||
switch {
|
||||
@@ -649,10 +645,10 @@ func (p *parser) parseSimpleKey(b []byte) (key, rest []byte, err error) {
|
||||
case b[0] == '"':
|
||||
return p.parseBasicString(b)
|
||||
case isUnquotedKeyChar(b[0]):
|
||||
return scanUnquotedKey(b)
|
||||
key, rest = scanUnquotedKey(b)
|
||||
return key, rest, nil
|
||||
default:
|
||||
//nolint:godox
|
||||
return nil, nil, unexpectedCharacter{b: b} // TODO: should be unexpected EOF
|
||||
return nil, nil, newDecodeError(b[0:1], "invalid character at start of key: %c", b[0])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -825,11 +821,14 @@ byteLoop:
|
||||
c := b[i]
|
||||
|
||||
switch {
|
||||
case isDigit(c) || c == '-':
|
||||
case isDigit(c):
|
||||
case c == '-':
|
||||
const offsetOfTz = 19
|
||||
if i == offsetOfTz {
|
||||
hasTz = true
|
||||
}
|
||||
case c == 'T' || c == ':' || c == '.':
|
||||
hasTime = true
|
||||
|
||||
continue byteLoop
|
||||
case c == '+' || c == '-' || c == 'Z':
|
||||
hasTz = true
|
||||
case c == ' ':
|
||||
@@ -854,9 +853,6 @@ byteLoop:
|
||||
kind = ast.LocalDateTime
|
||||
}
|
||||
} else {
|
||||
if hasTz {
|
||||
return ast.Reference{}, nil, newDecodeError(b, "date-time has timezone but not time component")
|
||||
}
|
||||
kind = ast.LocalDate
|
||||
}
|
||||
|
||||
@@ -977,26 +973,9 @@ func isValidBinaryRune(r byte) bool {
|
||||
}
|
||||
|
||||
func expect(x byte, b []byte) ([]byte, error) {
|
||||
if len(b) == 0 {
|
||||
return nil, newDecodeError(b[:0], "expecting %#U", x)
|
||||
}
|
||||
|
||||
if b[0] != x {
|
||||
return nil, newDecodeError(b[0:1], "expected character %U", x)
|
||||
}
|
||||
|
||||
return b[1:], nil
|
||||
}
|
||||
|
||||
type unexpectedCharacter struct {
|
||||
r byte
|
||||
b []byte
|
||||
}
|
||||
|
||||
func (u unexpectedCharacter) Error() string {
|
||||
if len(u.b) == 0 {
|
||||
return fmt.Sprintf("expected %#U, not EOF", u.r)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("expected %#U, not %#U", u.r, u.b[0])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user