Allow empty quoted keys (#97)
This commit is contained in:
@@ -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,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
@@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user