mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-12-16 03:08:52 +08:00
fix: disallow dotkey and inline table migration
This commit is contained in:
@@ -1257,6 +1257,9 @@ std::string format_dotted_keys(InputIterator first, const InputIterator last)
|
|||||||
// forward decl for is_valid_forward_table_definition
|
// forward decl for is_valid_forward_table_definition
|
||||||
result<std::pair<std::vector<key>, region>, std::string>
|
result<std::pair<std::vector<key>, region>, std::string>
|
||||||
parse_table_key(location& loc);
|
parse_table_key(location& loc);
|
||||||
|
template<typename Value>
|
||||||
|
result<std::pair<typename Value::table_type, region>, std::string>
|
||||||
|
parse_inline_table(location& loc);
|
||||||
|
|
||||||
// The following toml file is allowed.
|
// The following toml file is allowed.
|
||||||
// ```toml
|
// ```toml
|
||||||
@@ -1282,16 +1285,41 @@ parse_table_key(location& loc);
|
|||||||
// of the key. If the key region points deeper node, it would be allowed.
|
// of the key. If the key region points deeper node, it would be allowed.
|
||||||
// Otherwise, the key points the same node. It would be rejected.
|
// Otherwise, the key points the same node. It would be rejected.
|
||||||
template<typename Value, typename Iterator>
|
template<typename Value, typename Iterator>
|
||||||
bool is_valid_forward_table_definition(const Value& fwd,
|
bool is_valid_forward_table_definition(const Value& fwd, const Value& inserting,
|
||||||
Iterator key_first, Iterator key_curr, Iterator key_last)
|
Iterator key_first, Iterator key_curr, Iterator key_last)
|
||||||
{
|
{
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// check type of the value to be inserted/merged
|
||||||
|
|
||||||
|
std::string inserting_reg = "";
|
||||||
|
if(const auto ptr = detail::get_region(inserting))
|
||||||
|
{
|
||||||
|
inserting_reg = ptr->str();
|
||||||
|
}
|
||||||
|
location inserting_def("internal", std::move(inserting_reg));
|
||||||
|
if(const auto inlinetable = parse_inline_table<Value>(inserting_def))
|
||||||
|
{
|
||||||
|
// check if we are overwriting existing table.
|
||||||
|
// ```toml
|
||||||
|
// # NG
|
||||||
|
// a.b = 42
|
||||||
|
// a = {d = 3.14}
|
||||||
|
// ```
|
||||||
|
// Inserting an inline table to a existing super-table is not allowed in
|
||||||
|
// any case. If we found it, we can reject it without further checking.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// check table defined before
|
||||||
|
|
||||||
std::string internal = "";
|
std::string internal = "";
|
||||||
if(const auto ptr = detail::get_region(fwd))
|
if(const auto ptr = detail::get_region(fwd))
|
||||||
{
|
{
|
||||||
internal = ptr->str();
|
internal = ptr->str();
|
||||||
}
|
}
|
||||||
location def("internal", std::move(internal));
|
location def("internal", std::move(internal));
|
||||||
if(const auto tabkeys = parse_table_key(def))
|
if(const auto tabkeys = parse_table_key(def)) // [table.key]
|
||||||
{
|
{
|
||||||
// table keys always contains all the nodes from the root.
|
// table keys always contains all the nodes from the root.
|
||||||
const auto& tks = tabkeys.unwrap().first;
|
const auto& tks = tabkeys.unwrap().first;
|
||||||
@@ -1481,7 +1509,7 @@ insert_nested_key(typename Value::table_type& root, const Value& v,
|
|||||||
if(tab->at(k).is_table() && v.is_table())
|
if(tab->at(k).is_table() && v.is_table())
|
||||||
{
|
{
|
||||||
if(!is_valid_forward_table_definition(
|
if(!is_valid_forward_table_definition(
|
||||||
tab->at(k), first, iter, last))
|
tab->at(k), v, first, iter, last))
|
||||||
{
|
{
|
||||||
throw syntax_error(format_underline(concat_to_string(
|
throw syntax_error(format_underline(concat_to_string(
|
||||||
"toml::insert_value: table (\"",
|
"toml::insert_value: table (\"",
|
||||||
|
|||||||
Reference in New Issue
Block a user