toml: check for immutable tables (#12612)

pull/12616/head
Larpon 2021-11-29 14:10:23 +01:00 committed by GitHub
parent c14c324125
commit 65e9503556
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 18 deletions

View File

@ -259,6 +259,17 @@ fn (mut p Parser) expect(expected_token token.Kind) ? {
}
}
// build_explicitly_declared_key returns the absolute dotted key path.
fn (p Parser) build_explicitly_declared_key(key DottedKey) DottedKey {
if p.root_map_key.len > 0 {
mut abs_dotted_key := DottedKey([]string{})
abs_dotted_key << p.root_map_key
abs_dotted_key << key
return abs_dotted_key
}
return key
}
// check_explicitly_declared returns an error if `key` has been explicitly declared.
fn (p Parser) check_explicitly_declared(key DottedKey) ? {
if p.explicit_declared.len > 0 && p.explicit_declared.has(key) {
@ -461,19 +472,23 @@ pub fn (mut p Parser) root_table() ? {
sub_table, key := p.sub_table_key(dotted_key)
// Check for "table injection":
// https://github.com/BurntSushi/toml-test/blob/576db8523df1b8705ef18c526b4a6ba9c271bbbc/tests/invalid/table/injection-1.toml
// https://github.com/BurntSushi/toml-test/blob/576db8523df1b8705ef18c526b4a6ba9c271bbbc/tests/invalid/table/injection-2.toml
// NOTE this is a *relatively* costly check. In general - and by specification,
// NOTE these are *relatively* costly checks. In general - and by specification,
// TOML documents are expected to be "small" so this shouldn't be a problem. Famous last words.
for explicit_key in p.explicit_declared {
// Check for key re-defining:
// https://github.com/iarna/toml-spec-tests/blob/1880b1a/errors/inline-table-imutable-1.toml
if p.build_explicitly_declared_key(sub_table) == explicit_key {
return error(@MOD + '.' + @STRUCT + '.' + @FN +
' key `$sub_table` has already been explicitly declared. Unexpected redeclaration at "$p.tok.kind" "$p.tok.lit" in this (excerpt): "...${p.excerpt()}..."')
}
if explicit_key.len == 1 || explicit_key == p.root_map_key {
continue
}
mut abs_dotted_key := DottedKey([]string{})
abs_dotted_key << p.root_map_key
abs_dotted_key << sub_table
if abs_dotted_key.starts_with(explicit_key) {
// Check for "table injection":
// https://github.com/BurntSushi/toml-test/blob/576db85/tests/invalid/table/injection-1.toml
// https://github.com/BurntSushi/toml-test/blob/576db85/tests/invalid/table/injection-2.toml
if p.build_explicitly_declared_key(sub_table).starts_with(explicit_key) {
return error(@MOD + '.' + @STRUCT + '.' + @FN +
' key `$dotted_key` has already been explicitly declared. Unexpected redeclaration at "$p.tok.kind" "$p.tok.lit" in this (excerpt): "...${p.excerpt()}..."')
}
@ -488,14 +503,6 @@ pub fn (mut p Parser) root_table() ? {
p.ignore_while(parser.space_formatting)
key, val := p.key_value() ?
// Check and register explicitly declared arrays
if val is []ast.Value {
dotted_key := DottedKey([key.str()])
// Disallow re-declaring the key
p.check_explicitly_declared(dotted_key) ?
p.explicit_declared << dotted_key
}
t := p.find_table() ?
unsafe {
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting "$key.str()" = $val in table ${ptr_str(t)}')
@ -587,7 +594,7 @@ pub fn (mut p Parser) root_table() ? {
p.check_explicitly_declared(dotted_key) ?
p.explicit_declared << dotted_key
// Check for footgun re-declaration in this odd way:
// Check for footgun redeclaration in this odd way:
// [[tbl]]
// [tbl]
if p.last_aot == dotted_key {
@ -1212,6 +1219,11 @@ pub fn (mut p Parser) key_value() ?(ast.Key, ast.Value) {
p.ignore_while(parser.space_formatting)
value := p.value() ?
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed key value pair. `$key = $value`')
p.explicit_declared << p.build_explicitly_declared_key(DottedKey([
key.str(),
]))
return key, value
}
@ -1226,6 +1238,9 @@ pub fn (mut p Parser) dotted_key_value() ?(DottedKey, ast.Value) {
p.ignore_while(parser.space_formatting)
value := p.value() ?
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed dotted key value pair `$dotted_key = $value`...')
p.explicit_declared << p.build_explicitly_declared_key(dotted_key)
return dotted_key, value
}

View File

@ -18,7 +18,6 @@ const (
'errors/table-3.toml',
'errors/table-4.toml',
'errors/table-invalid-4.toml',
'errors/inline-table-imutable-1.toml',
]
valid_value_exceptions = []string{}