toml: fix implicit allocation overwrite of existing table (#12793)

pull/12795/head
Larpon 2021-12-11 14:21:46 +01:00 committed by GitHub
parent 9bf777c1ee
commit ba06eba39c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 8 deletions

View File

@ -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... // 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) ? { 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() ? dotted_key := p.dotted_key() ?
p.ignore_while(parser.space_formatting) 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 { unsafe {
// NOTE this is starting to get EVEN uglier. TOML is not *at all* simple at this point... // NOTE this is starting to get EVEN uglier. TOML is not *at all* simple at this point...
if first != p.last_aot { if first != p.last_aot {
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, '$first != $p.last_aot')
// Implicit allocation // Implicit allocation
if p.last_aot.len == 0 { if p.last_aot.len == 0 {
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'implicit allocation of array for dotted key `$dotted_key`.')
p.last_aot = first p.last_aot = first
// We register this implicit allocation as *explicit* to be able to catch mut nm := &p.root_map
// special cases like: if first.str() in table.keys() {
// https://github.com/BurntSushi/toml-test/blob/576db852/tests/invalid/table/array-implicit.toml util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'adding to existing table entry at `$first`.')
p.explicit_declared << 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{} nm[last.str()] = []ast.Value{}
table[first.str()] = ast.Value(nm) table[first.str()] = ast.Value(nm)

View File

@ -1,7 +1,8 @@
import toml import toml
import strconv import strconv
const toml_text = ' const (
toml_text = '
modules = [ "ui", "toml" ] modules = [ "ui", "toml" ]
errors = [] 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() { fn test_value_query_in_array() {
toml_doc := toml.parse(toml_text) or { panic(err) } toml_doc := toml.parse(toml_text) or { panic(err) }
mut value := toml_doc.value('themes[0].colors[1]').string() 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() value_u64 = toml_doc.value('values.minus-inf').u64()
assert value_u64 == strconv.double_minus_infinity 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
}