Allow empty quoted keys (#97)
This commit is contained in:
+14
-2
@@ -12,6 +12,7 @@ func parseKey(key string) ([]string, error) {
|
||||
groups := []string{}
|
||||
var buffer bytes.Buffer
|
||||
inQuotes := false
|
||||
wasInQuotes := false
|
||||
escapeNext := false
|
||||
ignoreSpace := true
|
||||
expectDot := false
|
||||
@@ -33,16 +34,27 @@ func parseKey(key string) ([]string, error) {
|
||||
escapeNext = true
|
||||
continue
|
||||
case '"':
|
||||
if inQuotes {
|
||||
groups = append(groups, buffer.String())
|
||||
buffer.Reset()
|
||||
wasInQuotes = true
|
||||
}
|
||||
inQuotes = !inQuotes
|
||||
expectDot = false
|
||||
case '.':
|
||||
if inQuotes {
|
||||
buffer.WriteRune(char)
|
||||
} else {
|
||||
groups = append(groups, buffer.String())
|
||||
buffer.Reset()
|
||||
if !wasInQuotes {
|
||||
if buffer.Len() == 0 {
|
||||
return nil, fmt.Errorf("empty key group")
|
||||
}
|
||||
groups = append(groups, buffer.String())
|
||||
buffer.Reset()
|
||||
}
|
||||
ignoreSpace = true
|
||||
expectDot = false
|
||||
wasInQuotes = false
|
||||
}
|
||||
case ' ':
|
||||
if inQuotes {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
func testResult(t *testing.T, key string, expected []string) {
|
||||
parsed, err := parseKey(key)
|
||||
t.Logf("key=%s expected=%s parsed=%s", key, expected, parsed)
|
||||
if err != nil {
|
||||
t.Fatal("Unexpected error:", err)
|
||||
}
|
||||
@@ -43,7 +44,13 @@ func TestBaseKeyPound(t *testing.T) {
|
||||
testError(t, "hello#world", "invalid bare character: #")
|
||||
}
|
||||
|
||||
func TestQuotedKeys(t *testing.T) {
|
||||
testResult(t, `hello."foo".bar`, []string{"hello", "foo", "bar"})
|
||||
testResult(t, `"hello!"`, []string{"hello!"})
|
||||
}
|
||||
|
||||
func TestEmptyKey(t *testing.T) {
|
||||
testError(t, "", "empty key")
|
||||
testError(t, " ", "empty key")
|
||||
testResult(t, `""`, []string{""})
|
||||
}
|
||||
|
||||
+11
-1
@@ -177,6 +177,16 @@ func TestStringEscapables(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestEmptyQuotedString(t *testing.T) {
|
||||
tree, err := Load(`[""]
|
||||
"" = 1`)
|
||||
assertTree(t, tree, err, map[string]interface{}{
|
||||
"": map[string]interface{}{
|
||||
"": int64(1),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestBools(t *testing.T) {
|
||||
tree, err := Load("a = true\nb = false")
|
||||
assertTree(t, tree, err, map[string]interface{}{
|
||||
@@ -446,7 +456,7 @@ func TestDuplicateKeys(t *testing.T) {
|
||||
|
||||
func TestEmptyIntermediateTable(t *testing.T) {
|
||||
_, err := Load("[foo..bar]")
|
||||
if err.Error() != "(1, 2): empty intermediate table" {
|
||||
if err.Error() != "(1, 2): invalid group array key: empty key group" {
|
||||
t.Error("Bad error message:", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,9 +222,6 @@ func (t *TomlTree) SetPath(keys []string, value interface{}) {
|
||||
func (t *TomlTree) createSubTree(keys []string, pos Position) error {
|
||||
subtree := t
|
||||
for _, intermediateKey := range keys {
|
||||
if intermediateKey == "" {
|
||||
return fmt.Errorf("empty intermediate table")
|
||||
}
|
||||
nextTree, exists := subtree.values[intermediateKey]
|
||||
if !exists {
|
||||
tree := newTomlTree()
|
||||
|
||||
Reference in New Issue
Block a user