diff --git a/README.md b/README.md index a760379..1a21f35 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/examples/error_printer.cpp b/examples/error_printer.cpp index 8366f18..01daf84 100644 --- a/examples/error_printer.cpp +++ b/examples/error_printer.cpp @@ -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, }; } diff --git a/include/toml++/toml_parser.h b/include/toml++/toml_parser.h index da72c0a..cb8db10 100644 --- a/include/toml++/toml_parser.h +++ b/include/toml++/toml_parser.h @@ -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 + friend std::basic_ostream& operator << (std::basic_ostream& os, const parse_result& result) + { + return result.is_err ? (os << result.error()) : (os << result.table()); + } }; #else diff --git a/include/toml++/toml_parser.hpp b/include/toml++/toml_parser.hpp index aa868e9..f38ac16 100644 --- a/include/toml++/toml_parser.hpp +++ b/include/toml++/toml_parser.hpp @@ -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(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(sizeof(chars)), " characters"sv + ); + chars[length++] = static_cast(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 diff --git a/tests/user_feedback.cpp b/tests/user_feedback.cpp index 59a15bc..f9e4105 100644 --- a/tests/user_feedback.cpp +++ b/tests/user_feedback.cpp @@ -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 ])" + ); } } diff --git a/toml.hpp b/toml.hpp index 79b3d52..5f6e8dd 100644 --- a/toml.hpp +++ b/toml.hpp @@ -7303,6 +7303,12 @@ TOML_NAMESPACE_START { return is_err ? const_table_iterator{} : table().cend(); } + + template + friend std::basic_ostream& operator << (std::basic_ostream& 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(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(sizeof(chars)), " characters"sv + ); + chars[length++] = static_cast(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