Allow empty quoted keys (#97)

This commit is contained in:
Thomas Pelletier
2016-09-06 22:25:57 +02:00
committed by GitHub
parent 5a62685873
commit 31055c2ff0
4 changed files with 32 additions and 6 deletions
+12
View File
@@ -12,6 +12,7 @@ func parseKey(key string) ([]string, error) {
groups := []string{} groups := []string{}
var buffer bytes.Buffer var buffer bytes.Buffer
inQuotes := false inQuotes := false
wasInQuotes := false
escapeNext := false escapeNext := false
ignoreSpace := true ignoreSpace := true
expectDot := false expectDot := false
@@ -33,16 +34,27 @@ func parseKey(key string) ([]string, error) {
escapeNext = true escapeNext = true
continue continue
case '"': case '"':
if inQuotes {
groups = append(groups, buffer.String())
buffer.Reset()
wasInQuotes = true
}
inQuotes = !inQuotes inQuotes = !inQuotes
expectDot = false expectDot = false
case '.': case '.':
if inQuotes { if inQuotes {
buffer.WriteRune(char) buffer.WriteRune(char)
} else { } else {
if !wasInQuotes {
if buffer.Len() == 0 {
return nil, fmt.Errorf("empty key group")
}
groups = append(groups, buffer.String()) groups = append(groups, buffer.String())
buffer.Reset() buffer.Reset()
}
ignoreSpace = true ignoreSpace = true
expectDot = false expectDot = false
wasInQuotes = false
} }
case ' ': case ' ':
if inQuotes { if inQuotes {
+7
View File
@@ -7,6 +7,7 @@ import (
func testResult(t *testing.T, key string, expected []string) { func testResult(t *testing.T, key string, expected []string) {
parsed, err := parseKey(key) parsed, err := parseKey(key)
t.Logf("key=%s expected=%s parsed=%s", key, expected, parsed)
if err != nil { if err != nil {
t.Fatal("Unexpected error:", err) t.Fatal("Unexpected error:", err)
} }
@@ -43,7 +44,13 @@ func TestBaseKeyPound(t *testing.T) {
testError(t, "hello#world", "invalid bare character: #") 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) { func TestEmptyKey(t *testing.T) {
testError(t, "", "empty key") testError(t, "", "empty key")
testError(t, " ", "empty key") testError(t, " ", "empty key")
testResult(t, `""`, []string{""})
} }
+11 -1
View File
@@ -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) { func TestBools(t *testing.T) {
tree, err := Load("a = true\nb = false") tree, err := Load("a = true\nb = false")
assertTree(t, tree, err, map[string]interface{}{ assertTree(t, tree, err, map[string]interface{}{
@@ -446,7 +456,7 @@ func TestDuplicateKeys(t *testing.T) {
func TestEmptyIntermediateTable(t *testing.T) { func TestEmptyIntermediateTable(t *testing.T) {
_, err := Load("[foo..bar]") _, 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()) t.Error("Bad error message:", err.Error())
} }
} }
-3
View File
@@ -222,9 +222,6 @@ func (t *TomlTree) SetPath(keys []string, value interface{}) {
func (t *TomlTree) createSubTree(keys []string, pos Position) error { func (t *TomlTree) createSubTree(keys []string, pos Position) error {
subtree := t subtree := t
for _, intermediateKey := range keys { for _, intermediateKey := range keys {
if intermediateKey == "" {
return fmt.Errorf("empty intermediate table")
}
nextTree, exists := subtree.values[intermediateKey] nextTree, exists := subtree.values[intermediateKey]
if !exists { if !exists {
tree := newTomlTree() tree := newTomlTree()