fixed parser not handling overlong float literals correctly

also a few other edge cases (see #65)
This commit is contained in:
Mark Gillard 2020-10-10 11:45:53 +03:00
parent 33f7d732a1
commit 30b756f993
6 changed files with 53 additions and 22 deletions

View File

@ -203,7 +203,7 @@ UTF-8 decoding is performed using a state machine based on Bjoern Hoehrmann's '[
- **[@Reedbeta](https://github.com/Reedbeta)** - Fixed a bug and added additional Visual Studio debugger native visualizers
- **[@shdnx](https://github.com/shdnx)** - Fixed a bug on GCC 8.2.0 and some meson config issues
- **[@sobczyk](https://github.com/sobczyk)** - Reported some bugs
- **[@sneves](https://github.com/sneves)** - Reported a bug
- **[@sneves](https://github.com/sneves)** - Helped fix a number of parser bugs
- **[@traversaro](https://github.com/traversaro)** - Added vcpkg support and reported a bunch of bugs
- **[@ximion](https://github.com/ximion)** - Added support for installation with meson
- **[@whiterabbit963](https://github.com/whiterabbit963)** - Fixed a bug with value_or conversions

View File

@ -98,7 +98,10 @@ namespace
R"(val = 1_0_ )"sv,
R"(val = 999999999999999999999999999999999999 )"sv,
R"(val = 9223372036854775808 )"sv,
R"(val = 01 )"sv
R"(val = 01 )"sv,
"########## floats"sv,
R"(val = 9999999999999999999999999999999999999999999999999999999999999995.0)"sv,
};
}

View File

@ -315,6 +315,13 @@ TOML_NAMESPACE_START
{
return is_err ? const_table_iterator{} : table().cend();
}
/// \brief Prints the held error or table object out to a text stream.
template <typename Char>
friend std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& os, const parse_result& result)
{
return result.is_err ? (os << result.error()) : (os << result.table());
}
};
#else

View File

@ -559,6 +559,7 @@ TOML_IMPL_NAMESPACE_START
{
if (consume_line_break())
return true;
return_if_error({});
if constexpr (TOML_LANG_AT_LEAST(1, 0, 0))
{
@ -896,7 +897,7 @@ TOML_IMPL_NAMESPACE_START
std::string str;
do
{
assert_not_error();
return_if_error({});
// handle closing delimiters
if (*cp == U'\'')
@ -957,6 +958,7 @@ TOML_IMPL_NAMESPACE_START
if (multi_line && is_line_break(*cp))
{
consume_line_break();
return_if_error({});
str += '\n';
continue;
}
@ -1194,10 +1196,6 @@ TOML_IMPL_NAMESPACE_START
else if (!is_match(*prev, U'e', U'E'))
set_error_and_return_default("expected exponent digit, saw '"sv, to_sv(*cp), "'"sv);
}
else if (length == sizeof(chars))
set_error_and_return_default(
"exceeds maximum length of "sv, static_cast<uint64_t>(sizeof(chars)), " characters"sv
);
else if (is_decimal_digit(*cp))
{
if (!seen_decimal)
@ -1211,6 +1209,11 @@ TOML_IMPL_NAMESPACE_START
else
set_error_and_return_default("expected decimal digit, saw '"sv, to_sv(*cp), "'"sv);
if (length == sizeof(chars))
set_error_and_return_default(
"exceeds maximum length of "sv, static_cast<uint64_t>(sizeof(chars)), " characters"sv
);
chars[length++] = static_cast<char>(cp->bytes[0]);
prev = cp;
advance_and_return_if_error({});
@ -2719,7 +2722,6 @@ TOML_IMPL_NAMESPACE_START
|| consume_line_break()
|| consume_comment())
continue;
return_if_error();
// [tables]
@ -2944,6 +2946,7 @@ TOML_IMPL_NAMESPACE_START
while (consume_leading_whitespace())
continue;
}
return_if_error({});
set_error_and_return_if_eof({});
// commas - only legal after a key-value pair

View File

@ -92,17 +92,26 @@ TEST_CASE("user feedback")
{
// see: https://github.com/marzer/tomlplusplus/issues/65
// this tests two things:
// these test a number of things
// - a comment at EOF
// - a malformed UTF-8 sequence
//
// it should fail to parse, but correctly issue an error (not crash!)
// - a malformed UTF-8 sequence in a comment
// - a malformed UTF-8 sequence during a KVP
// - overlong numeric literals
// all should fail to parse, but correctly issue an error (not crash!)
parsing_should_fail(FILE_LINE_ARGS, "#\xf1\x63");
// a malformed UTF-8 sequence during a KVP
//
// it should fail to parse, but correctly issue an error (not crash!)
parsing_should_fail(FILE_LINE_ARGS, "1= 0x6cA#+\xf1");
parsing_should_fail(FILE_LINE_ARGS, "p=06:06:06#\x0b\xff");
parsing_should_fail(FILE_LINE_ARGS, "''''d' 't' '+o\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
"\x0c\x0c\x0c\x0c\x0c\r\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
"\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
"\x0c\x0c\x0c\x0c\x0c\x0c\x0cop1\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
"\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
"\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c' 'ml'\n\n%\x87"
);
parsing_should_fail(FILE_LINE_ARGS,
R"(t =[ 9, 2, 1,"r", 9999999999999999999999999999999999999999999999999999999999999995.0 ])"
);
}
}

View File

@ -7303,6 +7303,12 @@ TOML_NAMESPACE_START
{
return is_err ? const_table_iterator{} : table().cend();
}
template <typename Char>
friend std::basic_ostream<Char>& operator << (std::basic_ostream<Char>& os, const parse_result& result)
{
return result.is_err ? (os << result.error()) : (os << result.table());
}
};
#else
@ -9276,6 +9282,7 @@ TOML_IMPL_NAMESPACE_START
{
if (consume_line_break())
return true;
return_if_error({});
if constexpr (TOML_LANG_AT_LEAST(1, 0, 0))
{
@ -9613,7 +9620,7 @@ TOML_IMPL_NAMESPACE_START
std::string str;
do
{
assert_not_error();
return_if_error({});
// handle closing delimiters
if (*cp == U'\'')
@ -9674,6 +9681,7 @@ TOML_IMPL_NAMESPACE_START
if (multi_line && is_line_break(*cp))
{
consume_line_break();
return_if_error({});
str += '\n';
continue;
}
@ -9911,10 +9919,6 @@ TOML_IMPL_NAMESPACE_START
else if (!is_match(*prev, U'e', U'E'))
set_error_and_return_default("expected exponent digit, saw '"sv, to_sv(*cp), "'"sv);
}
else if (length == sizeof(chars))
set_error_and_return_default(
"exceeds maximum length of "sv, static_cast<uint64_t>(sizeof(chars)), " characters"sv
);
else if (is_decimal_digit(*cp))
{
if (!seen_decimal)
@ -9928,6 +9932,11 @@ TOML_IMPL_NAMESPACE_START
else
set_error_and_return_default("expected decimal digit, saw '"sv, to_sv(*cp), "'"sv);
if (length == sizeof(chars))
set_error_and_return_default(
"exceeds maximum length of "sv, static_cast<uint64_t>(sizeof(chars)), " characters"sv
);
chars[length++] = static_cast<char>(cp->bytes[0]);
prev = cp;
advance_and_return_if_error({});
@ -11433,7 +11442,6 @@ TOML_IMPL_NAMESPACE_START
|| consume_line_break()
|| consume_comment())
continue;
return_if_error();
// [tables]
@ -11657,6 +11665,7 @@ TOML_IMPL_NAMESPACE_START
while (consume_leading_whitespace())
continue;
}
return_if_error({});
set_error_and_return_if_eof({});
// commas - only legal after a key-value pair