From ba06eba39c7a63e34990039ce41325c7720cdafa Mon Sep 17 00:00:00 2001 From: Larpon Date: Sat, 11 Dec 2021 14:21:46 +0100 Subject: [PATCH] toml: fix implicit allocation overwrite of existing table (#12793) --- vlib/toml/parser/parser.v | 22 +++++++++++++++------- vlib/toml/tests/value_query_test.v | 21 ++++++++++++++++++++- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/vlib/toml/parser/parser.v b/vlib/toml/parser/parser.v index dd242ba145..f0bb7874e2 100644 --- a/vlib/toml/parser/parser.v +++ b/vlib/toml/parser/parser.v @@ -888,7 +888,7 @@ pub fn (mut p Parser) array_of_tables_contents() ?[]ast.Value { // double_array_of_tables parses next tokens into an array of tables of arrays of `ast.Value`s... pub fn (mut p Parser) double_array_of_tables(mut table map[string]ast.Value) ? { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing array of tables of arrays "$p.tok.kind" "$p.tok.lit"') + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing nested array of tables "$p.tok.kind" "$p.tok.lit"') dotted_key := p.dotted_key() ? p.ignore_while(parser.space_formatting) @@ -918,16 +918,24 @@ pub fn (mut p Parser) double_array_of_tables(mut table map[string]ast.Value) ? { unsafe { // NOTE this is starting to get EVEN uglier. TOML is not *at all* simple at this point... if first != p.last_aot { + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, '$first != $p.last_aot') // Implicit allocation if p.last_aot.len == 0 { - util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'implicit allocation of array for dotted key `$dotted_key`.') p.last_aot = first - // We register this implicit allocation as *explicit* to be able to catch - // special cases like: - // https://github.com/BurntSushi/toml-test/blob/576db852/tests/invalid/table/array-implicit.toml - p.explicit_declared << first + mut nm := &p.root_map + if first.str() in table.keys() { + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'adding to existing table entry at `$first`.') + nm = &(table[first.str()] as map[string]ast.Value) + } else { + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'implicit allocation of map for `$first` in dotted key `$dotted_key`.') + new := map[string]ast.Value{} + nm = &new + // We register this implicit allocation as *explicit* to be able to catch + // special cases like: + // https://github.com/BurntSushi/toml-test/blob/576db852/tests/invalid/table/array-implicit.toml + p.explicit_declared << first + } - mut nm := map[string]ast.Value{} nm[last.str()] = []ast.Value{} table[first.str()] = ast.Value(nm) diff --git a/vlib/toml/tests/value_query_test.v b/vlib/toml/tests/value_query_test.v index c9f1aeaeb3..1c8312368a 100644 --- a/vlib/toml/tests/value_query_test.v +++ b/vlib/toml/tests/value_query_test.v @@ -1,7 +1,8 @@ import toml import strconv -const toml_text = ' +const ( + toml_text = ' modules = [ "ui", "toml" ] errors = [] @@ -37,6 +38,17 @@ colors = [ ] ' + toml_text_2 = " +[defaults] + run.flags = ['-f 1'] + + [[defaults.env]] + 'RUN_PATH' = '\$OUT_PATH' + 'RUN_TIME' = 5 + 'TEST_PATH' = '/tmp/test' +" +) + fn test_value_query_in_array() { toml_doc := toml.parse(toml_text) or { panic(err) } mut value := toml_doc.value('themes[0].colors[1]').string() @@ -92,3 +104,10 @@ fn test_inf_and_nan_query() { value_u64 = toml_doc.value('values.minus-inf').u64() assert value_u64 == strconv.double_minus_infinity } + +fn test_any_value_query_2() { + toml_doc := toml.parse(toml_text_2) or { panic(err) } + defaults := toml_doc.value('defaults') + assert defaults.value('run.flags[0]').string() == '-f 1' + assert defaults.value('env[0].RUN_TIME').int() == 5 +}