Skip to content

Commit

Permalink
fixed inline tables being mutable through regular table headers (closes
Browse files Browse the repository at this point in the history
  • Loading branch information
marzer committed Jan 5, 2022
1 parent de2413e commit a35ded8
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 54 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ code changes at callsites or in build systems are indicated with ⚠️.
- fixed parser not correctly round-tripping the format of binary and octal integers in some cases
- fixed strong exception guarantee edge-cases in `toml::table` and `toml::array`
- fixed some incorrect unicode scalar sequence transformations (#125)
- fixed a number of spec conformance issues (#127, #128, #129) (@moorereason)
- fixed a number of spec conformance issues (#127, #128, #129, #130, #131) (@moorereason)

#### Additions:
- added `operator->` to `toml::value` for class types
Expand Down
1 change: 1 addition & 0 deletions examples/error_printer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace
"val = {a='b',"sv,
"val = {a='b',\n c='d'}"sv, // allowed when TOML_ENABLE_UNRELEASED_FEATURES == 1
"val = {?='b'}"sv,
"foo = {} \n [foo.bar]"sv,

"########## tables"sv,
"[]"sv,
Expand Down
70 changes: 45 additions & 25 deletions include/toml++/impl/parser.inl
Original file line number Diff line number Diff line change
Expand Up @@ -783,10 +783,7 @@ TOML_ANON_NAMESPACE_START
#endif
}

error_builder(const error_builder&) = delete;
error_builder(error_builder&&) = delete;
error_builder& operator=(const error_builder&) = delete;
error_builder& operator=(error_builder&&) = delete;
TOML_DELETE_DEFAULTS(error_builder);
};

struct parse_scope
Expand All @@ -807,16 +804,13 @@ TOML_ANON_NAMESPACE_START
storage_ = parent_;
}

parse_scope(const parse_scope&) = delete;
parse_scope(parse_scope&&) = delete;
parse_scope& operator=(const parse_scope&) = delete;
parse_scope& operator=(parse_scope&&) = delete;
TOML_DELETE_DEFAULTS(parse_scope);
};
#define push_parse_scope_2(scope, line) parse_scope ps_##line(current_scope, scope)
#define push_parse_scope_1(scope, line) push_parse_scope_2(scope, line)
#define push_parse_scope(scope) push_parse_scope_1(scope, __LINE__)

struct parsed_key_buffer
struct parse_key_buffer
{
std::string buffer;
std::vector<std::pair<size_t, size_t>> segments;
Expand Down Expand Up @@ -864,32 +858,49 @@ TOML_ANON_NAMESPACE_START
}
};

struct parse_depth_counter
struct depth_counter_scope
{
size_t& depth_;

TOML_NODISCARD_CTOR
explicit parse_depth_counter(size_t& depth) noexcept : depth_{ depth }
explicit depth_counter_scope(size_t& depth) noexcept //
: depth_{ depth }
{
depth_++;
}

~parse_depth_counter() noexcept
~depth_counter_scope() noexcept
{
depth_--;
}

parse_depth_counter(const parse_depth_counter&) = delete;
parse_depth_counter(parse_depth_counter&&) = delete;
parse_depth_counter& operator=(const parse_depth_counter&) = delete;
parse_depth_counter& operator=(parse_depth_counter&&) = delete;
TOML_DELETE_DEFAULTS(depth_counter_scope);
};

struct parsed_string
{
std::string_view value;
bool was_multi_line;
};

struct table_vector_scope
{
std::vector<table*>& tables;

TOML_NODISCARD_CTOR
explicit table_vector_scope(std::vector<table*>& tables_, table& tbl) //
: tables{ tables_ }
{
tables.push_back(&tbl);
}

~table_vector_scope() noexcept
{
tables.pop_back();
}

TOML_DELETE_DEFAULTS(table_vector_scope);
};
}
TOML_ANON_NAMESPACE_END;

Expand Down Expand Up @@ -1013,8 +1024,9 @@ TOML_IMPL_NAMESPACE_START
const utf8_codepoint* cp = {};
std::vector<table*> implicit_tables;
std::vector<table*> dotted_key_tables;
std::vector<table*> open_inline_tables;
std::vector<array*> table_arrays;
parsed_key_buffer key_buffer;
parse_key_buffer key_buffer;
std::string string_buffer;
std::string recording_buffer; // for diagnostics
bool recording = false, recording_whitespace = true;
Expand All @@ -1038,10 +1050,7 @@ TOML_IMPL_NAMESPACE_START
void set_error_at(source_position pos, const T&... reason) const
{
static_assert(sizeof...(T) > 0);
#if !TOML_EXCEPTIONS
if (err)
return;
#endif
return_if_error();

error_builder builder{ current_scope };
(builder.append(reason), ...);
Expand Down Expand Up @@ -2452,8 +2461,8 @@ TOML_IMPL_NAMESPACE_START
TOML_ASSERT_ASSUME(!is_value_terminator(*cp));
push_parse_scope("value"sv);

const parse_depth_counter depth_counter{ nested_values };
if (nested_values > max_nested_values)
const depth_counter_scope depth_counter{ nested_values };
if TOML_UNLIKELY(nested_values > max_nested_values)
set_error_and_return_default("exceeded maximum nested value depth of "sv,
static_cast<uint64_t>(max_nested_values),
" (TOML_MAX_NESTED_VALUES)"sv);
Expand Down Expand Up @@ -3099,7 +3108,15 @@ TOML_IMPL_NAMESPACE_START
node& p = pit->second;

if (auto tbl = p.as_table())
{
// adding to closed inline tables is illegal
if (tbl->is_inline() && !impl::find(open_inline_tables.begin(), open_inline_tables.end(), tbl))
set_error_and_return_default("cannot insert '"sv,
to_sv(recording_buffer),
"' into existing inline table"sv);

parent = tbl;
}
else if (auto arr = p.as_array(); arr && impl::find(table_arrays.begin(), table_arrays.end(), arr))
{
// table arrays are a special case;
Expand Down Expand Up @@ -3264,7 +3281,9 @@ TOML_IMPL_NAMESPACE_START
if (pit != tbl->end() && pit->first == segment)
{
table* p = pit->second.as_table();
if (!p

// redefinition
if TOML_UNLIKELY(!p
|| !(impl::find(dotted_key_tables.begin(), dotted_key_tables.end(), p)
|| impl::find(implicit_tables.begin(), implicit_tables.end(), p)))
{
Expand Down Expand Up @@ -3523,14 +3542,15 @@ TOML_IMPL_NAMESPACE_START
node_ptr tbl_ptr{ new table{} };
table& tbl = tbl_ptr->ref_cast<table>();
tbl.is_inline(true);
table_vector_scope table_scope{ open_inline_tables, tbl };

enum TOML_CLOSED_ENUM parse_elem : int
{
none,
comma,
kvp
};
parse_elem prev = none;

while (!is_error())
{
if constexpr (TOML_LANG_UNRELEASED) // toml/issues/516 (newlines/trailing commas in inline tables)
Expand Down
9 changes: 6 additions & 3 deletions include/toml++/impl/preprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -517,9 +517,6 @@
//# ATTRIBUTES, UTILITY MACROS ETC
//#====================================================================================================================




#if TOML_GCC || TOML_CLANG || (TOML_ICC && !TOML_ICC_CL)
// not supported by any version of GCC or Clang as of 26/11/2020
// not supported by any version of ICC on Linux as of 11/01/2021
Expand Down Expand Up @@ -748,6 +745,12 @@

#define TOML_UNUSED(...) static_cast<void>(__VA_ARGS__)

#define TOML_DELETE_DEFAULTS(T) \
T(const T&) = delete; \
T(T&&) = delete; \
T& operator=(const T&) = delete; \
T& operator=(T&&) = delete

//======================================================================================================================
// SFINAE
//======================================================================================================================
Expand Down
1 change: 1 addition & 0 deletions include/toml++/toml.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ TOML_POP_WARNINGS;
#undef TOML_CONST_GETTER
#undef TOML_CONST_INLINE_GETTER
#undef TOML_CONSTRAINED_TEMPLATE
#undef TOML_DELETE_DEFAULTS
#undef TOML_DISABLE_ARITHMETIC_WARNINGS
#undef TOML_DISABLE_CODE_ANALYSIS_WARNINGS
#undef TOML_DISABLE_SPAM_WARNINGS
Expand Down
8 changes: 8 additions & 0 deletions tests/user_feedback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,12 @@ b = []
parse_expected_value(FILE_LINE_ARGS, "0400-01-01T00:00:00"sv, toml::date_time{ { 400, 1, 1 }, { 0, 0, 0 } });
parse_expected_value(FILE_LINE_ARGS, "1000-01-01 00:00:00"sv, toml::date_time{ { 1000, 1, 1 }, { 0, 0, 0 } });
}

SECTION("github/issues/131") // https://github.com/marzer/tomlplusplus/issues/131
{
parsing_should_fail(FILE_LINE_ARGS, R"(
a={}
[a.b]
)"sv);
}
}
Loading

0 comments on commit a35ded8

Please sign in to comment.