From d05497900e23ad60ab59518537c33e6af3656f0e Mon Sep 17 00:00:00 2001 From: Allen Date: Tue, 5 May 2020 01:06:37 +0800 Subject: [PATCH] Forbid adding keys to exist inline table (#378) --- parser.go | 11 +++++++++++ parser_test.go | 28 ++++++++++++++++++++++++++++ toml.go | 2 ++ 3 files changed, 41 insertions(+) diff --git a/parser.go b/parser.go index 1b344fee..3da5677f 100644 --- a/parser.go +++ b/parser.go @@ -158,6 +158,11 @@ func (p *tomlParser) parseGroup() tomlParserStateFn { if err := p.tree.createSubTree(keys, startToken.Position); err != nil { p.raiseError(key, "%s", err) } + destTree := p.tree.GetPath(keys) + if target, ok := destTree.(*Tree); ok && target != nil && target.inline { + p.raiseError(key, "could not re-define exist inline table or its sub-table : %s", + strings.Join(keys, ".")) + } p.assume(tokenRightBracket) p.currentTable = keys return p.parseStart @@ -201,6 +206,11 @@ func (p *tomlParser) parseAssign() tomlParserStateFn { strings.Join(tableKey, ".")) } + if targetNode.inline { + p.raiseError(key, "could not add key or sub-table to exist inline table or its sub-table : %s", + strings.Join(tableKey, ".")) + } + // assign value to the found table keyVal := parsedKey[len(parsedKey)-1] localKey := []string{keyVal} @@ -411,6 +421,7 @@ Loop: if tokenIsComma(previous) { p.raiseError(previous, "trailing comma at the end of inline table") } + tree.inline = true return tree } diff --git a/parser_test.go b/parser_test.go index 4c5a65e0..b33c7766 100644 --- a/parser_test.go +++ b/parser_test.go @@ -703,6 +703,34 @@ func TestInlineTableTrailingComma(t *testing.T) { } } +func TestAddKeyToInlineTable(t *testing.T) { + _, err := Load("type = { name = \"Nail\" }\ntype.edible = false") + if err.Error() != "(2, 1): could not add key or sub-table to exist inline table or its sub-table : type" { + t.Error("Bad error message:", err.Error()) + } +} + +func TestAddSubTableToInlineTable(t *testing.T) { + _, err := Load("a = { b = \"c\" }\na.d.e = \"f\"") + if err.Error() != "(2, 1): could not add key or sub-table to exist inline table or its sub-table : a.d" { + t.Error("Bad error message:", err.Error()) + } +} + +func TestAddKeyToSubTableOfInlineTable(t *testing.T) { + _, err := Load("a = { b = { c = \"d\" } }\na.b.e = \"f\"") + if err.Error() != "(2, 1): could not add key or sub-table to exist inline table or its sub-table : a.b" { + t.Error("Bad error message:", err.Error()) + } +} + +func TestReDefineInlineTable(t *testing.T) { + _, err := Load("a = { b = \"c\" }\n[a]\n d = \"e\"") + if err.Error() != "(2, 2): could not re-define exist inline table or its sub-table : a" { + t.Error("Bad error message:", err.Error()) + } +} + func TestDuplicateGroups(t *testing.T) { _, err := Load("[foo]\na=2\n[foo]b=3") if err.Error() != "(3, 2): duplicated tables" { diff --git a/toml.go b/toml.go index f4d56870..d323c39b 100644 --- a/toml.go +++ b/toml.go @@ -23,6 +23,7 @@ type Tree struct { values map[string]interface{} // string -> *tomlValue, *Tree, []*Tree comment string commented bool + inline bool position Position } @@ -311,6 +312,7 @@ func (t *Tree) createSubTree(keys []string, pos Position) error { if !exists { tree := newTreeWithPosition(Position{Line: t.position.Line + i, Col: t.position.Col}) tree.position = pos + tree.inline = subtree.inline subtree.values[intermediateKey] = tree nextTree = tree }