fixed date parsing when the year has a leading zero (closes #130)
also: - fixed omitting value part from hex/bin/oct being accepted without error (closes #129) - added spec bug github template
This commit is contained in:
parent
b41e12f736
commit
de2413e0ef
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Found a bug? Help me squash it.
|
||||
about: Regular ol' bugs.
|
||||
title: ''
|
||||
labels: bug
|
||||
labels: [ "bug" ]
|
||||
assignees: marzer
|
||||
|
||||
---
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
---
|
||||
name: TOML spec conformance bug
|
||||
about: Bugs relating to the library's TOML spec conformance (or lack thereof).
|
||||
title: ''
|
||||
labels: [ "bug", "TOML spec" ]
|
||||
assignees: marzer
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
Replace the HTML/TOML comments below with the requested information.
|
||||
Please don't delete this template and roll your own!
|
||||
|
||||
Thanks for contributing!
|
||||
-->
|
||||
|
||||
|
||||
## The non-conforming TOML snippet
|
||||
```toml
|
||||
|
||||
# your TOML here
|
||||
|
||||
```
|
||||
|
||||
|
||||
## What you expected
|
||||
<!--
|
||||
e.g. a link to, or snippet from, the TOML spec, or some reasonable description thereof
|
||||
-->
|
||||
|
||||
|
||||
## What you got
|
||||
<!--
|
||||
e.g toml-test output
|
||||
-->
|
||||
|
||||
|
||||
## Environment
|
||||
**toml++ version and/or commit hash:**
|
||||
<!--
|
||||
If you're using the single-header version of the library, the version number is right at the top of the file.
|
||||
Otherwise you can find it by opening toml++/impl/version.h; it'll be represented by three defines -
|
||||
TOML_LIB_MAJOR, TOML_LIB_MINOR and TOML_LIB_PATCH.
|
||||
|
||||
If you're not using any particular release and are instead just living large at HEAD of master, the commit hash
|
||||
would be super helpful too, though it's not critical.
|
||||
|
||||
-->
|
||||
|
||||
**Any other useful information:**
|
||||
<!--
|
||||
Anything else you think will help me fix the issue. Since this report is for general spec conformance handling
|
||||
you probably don't need to worry about compiler versions, compilation flags, et cetera, though include them if
|
||||
you feel they're relevant.
|
||||
-->
|
|
@ -35,9 +35,8 @@ code changes at callsites or in build systems are indicated with ⚠️.
|
|||
- fixed missing `TOML_API` on interfaces
|
||||
- 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) (@moorereason)
|
||||
- fixed extended-precision fractional times causing parse error instead of truncating per the spec (#127) (@moorereason)
|
||||
- fixed some non-spec vertical whitespace being accepted as line breaks (#128) (@moorereason)
|
||||
- fixed some incorrect unicode scalar sequence transformations (#125)
|
||||
- fixed a number of spec conformance issues (#127, #128, #129) (@moorereason)
|
||||
|
||||
#### Additions:
|
||||
- added `operator->` to `toml::value` for class types
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
enum class formatted_string_traits : unsigned
|
||||
enum class TOML_CLOSED_FLAGS_ENUM formatted_string_traits : unsigned
|
||||
{
|
||||
none,
|
||||
line_breaks = 1u << 0, // \n
|
||||
|
|
|
@ -264,7 +264,7 @@ TOML_NAMESPACE_START // abi namespace
|
|||
}
|
||||
|
||||
/// \brief Metadata associated with TOML values.
|
||||
enum class TOML_OPEN_FLAGS_ENUM value_flags : uint16_t
|
||||
enum class TOML_OPEN_FLAGS_ENUM value_flags : uint16_t // being an "OPEN" flags enum is not an error
|
||||
{
|
||||
/// \brief None.
|
||||
none,
|
||||
|
|
|
@ -2088,6 +2088,9 @@ TOML_IMPL_NAMESPACE_START
|
|||
if (*cp != traits::prefix_codepoint)
|
||||
set_error_and_return_default("expected '"sv, traits::prefix, "', saw '"sv, to_sv(*cp), "'"sv);
|
||||
advance_and_return_if_error_or_eof({});
|
||||
|
||||
if (!traits::is_digit(*cp))
|
||||
set_error_and_return_default("expected digit, saw '"sv, to_sv(*cp), "'"sv);
|
||||
}
|
||||
|
||||
// consume value chars
|
||||
|
@ -2400,7 +2403,6 @@ TOML_IMPL_NAMESPACE_START
|
|||
node_ptr parse_inline_table();
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_NEVER_INLINE
|
||||
node_ptr parse_value_known_prefixes()
|
||||
{
|
||||
return_if_error({});
|
||||
|
@ -2505,8 +2507,8 @@ TOML_IMPL_NAMESPACE_START
|
|||
begins_zero = 1 << 14,
|
||||
|
||||
signs_msk = has_plus | has_minus,
|
||||
bzero_msk = begins_zero | has_digits,
|
||||
bdigit_msk = begins_digit | has_digits,
|
||||
bdigit_msk = has_digits | begins_digit,
|
||||
bzero_msk = bdigit_msk | begins_zero,
|
||||
};
|
||||
value_traits traits = has_nothing;
|
||||
const auto has_any = [&](auto t) noexcept { return (traits & t) != has_nothing; };
|
||||
|
@ -2516,7 +2518,11 @@ TOML_IMPL_NAMESPACE_START
|
|||
// examine the first character to get the 'begins with' traits
|
||||
// (good fail-fast opportunity; all the remaining types begin with numeric digits or signs)
|
||||
if (is_decimal_digit(*cp))
|
||||
add_trait(*cp == U'0' ? begins_zero : begins_digit);
|
||||
{
|
||||
add_trait(begins_digit);
|
||||
if (*cp == U'0')
|
||||
add_trait(begins_zero);
|
||||
}
|
||||
else if (is_match(*cp, U'+', U'-'))
|
||||
add_trait(begins_sign);
|
||||
else
|
||||
|
@ -2601,8 +2607,12 @@ TOML_IMPL_NAMESPACE_START
|
|||
return_if_error({});
|
||||
|
||||
// force further scanning if this could have been a date-time with a space instead of a T
|
||||
if (char_count == 10u && traits == (bdigit_msk | has_minus) && chars[4] == U'-' && chars[7] == U'-'
|
||||
&& !is_eof() && *cp == U' ')
|
||||
if (char_count == 10u //
|
||||
&& (traits | begins_zero) == (bzero_msk | has_minus) //
|
||||
&& chars[4] == U'-' //
|
||||
&& chars[7] == U'-' //
|
||||
&& !is_eof() //
|
||||
&& *cp == U' ')
|
||||
{
|
||||
const auto pre_advance_count = advance_count;
|
||||
const auto pre_scan_traits = traits;
|
||||
|
@ -2646,7 +2656,7 @@ TOML_IMPL_NAMESPACE_START
|
|||
// the only valid value type is an integer.
|
||||
if (char_count == 1u)
|
||||
{
|
||||
if (has_any(begins_zero | begins_digit))
|
||||
if (has_any(begins_digit))
|
||||
{
|
||||
val.reset(new value{ static_cast<int64_t>(chars[0] - U'0') });
|
||||
advance(); // skip the digit
|
||||
|
@ -2692,7 +2702,7 @@ TOML_IMPL_NAMESPACE_START
|
|||
val.reset(new value{ i });
|
||||
val->ref_cast<int64_t>().flags(flags);
|
||||
}
|
||||
else if (has_any(has_e) || (has_any(begins_zero | begins_digit) && chars[1] == U'.'))
|
||||
else if (has_any(has_e) || (has_any(begins_digit) && chars[1] == U'.'))
|
||||
val.reset(new value{ parse_float() });
|
||||
else if (has_any(begins_sign))
|
||||
{
|
||||
|
|
|
@ -152,6 +152,11 @@ TEST_CASE("parsing - integers (hex, bin, oct)")
|
|||
parsing_should_fail(FILE_LINE_ARGS, "val = 0o1000000000000000000000"sv);
|
||||
parsing_should_fail(FILE_LINE_ARGS, "val = 0b1000000000000000000000000000000000000000000000000000000000000000"sv);
|
||||
|
||||
// missing values after base prefix
|
||||
parsing_should_fail(FILE_LINE_ARGS, "val = 0x "sv);
|
||||
parsing_should_fail(FILE_LINE_ARGS, "val = 0o "sv);
|
||||
parsing_should_fail(FILE_LINE_ARGS, "val = 0b "sv);
|
||||
|
||||
// value tests
|
||||
parse_expected_value(FILE_LINE_ARGS, "0xDEADBEEF"sv, 0xDEADBEEF);
|
||||
parse_expected_value(FILE_LINE_ARGS, "0xdeadbeef"sv, 0xDEADBEEF);
|
||||
|
|
|
@ -230,4 +230,21 @@ b = []
|
|||
parsing_should_succeed(FILE_LINE_ARGS, "\t"sv);
|
||||
parsing_should_succeed(FILE_LINE_ARGS, "\n"sv);
|
||||
}
|
||||
|
||||
SECTION("github/issues/129") // https://github.com/marzer/tomlplusplus/issues/129
|
||||
{
|
||||
parsing_should_fail(FILE_LINE_ARGS, R"(
|
||||
hex = 0x
|
||||
oct = 0o
|
||||
bin = 0b
|
||||
)"sv);
|
||||
}
|
||||
|
||||
SECTION("github/issues/130") // https://github.com/marzer/tomlplusplus/issues/130
|
||||
{
|
||||
parse_expected_value(FILE_LINE_ARGS, "0400-01-01 00:00:00"sv, toml::date_time{ { 400, 1, 1 }, { 0, 0, 0 } });
|
||||
parse_expected_value(FILE_LINE_ARGS, "0400-01-01 "sv, toml::date{ 400, 1, 1 });
|
||||
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 } });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
<None Include=".github\ISSUE_TEMPLATE\bug_report.md" />
|
||||
<None Include=".github\ISSUE_TEMPLATE\config.yml" />
|
||||
<None Include=".github\ISSUE_TEMPLATE\feature_request.md" />
|
||||
<None Include=".github\ISSUE_TEMPLATE\spec_bug_report.md" />
|
||||
<None Include=".github\pull_request_template.md" />
|
||||
<None Include=".gitignore" />
|
||||
<None Include=".runsettings" />
|
||||
|
|
|
@ -217,6 +217,9 @@
|
|||
<None Include="include\toml++\impl\unicode.inl">
|
||||
<Filter>include\impl</Filter>
|
||||
</None>
|
||||
<None Include=".github\ISSUE_TEMPLATE\spec_bug_report.md">
|
||||
<Filter>.github</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include=".circleci">
|
||||
|
|
30
toml.hpp
30
toml.hpp
|
@ -1242,7 +1242,7 @@ TOML_NAMESPACE_START // abi namespace
|
|||
}
|
||||
}
|
||||
|
||||
enum class TOML_OPEN_FLAGS_ENUM value_flags : uint16_t
|
||||
enum class TOML_OPEN_FLAGS_ENUM value_flags : uint16_t // being an "OPEN" flags enum is not an error
|
||||
{
|
||||
none,
|
||||
format_as_binary = 1,
|
||||
|
@ -12698,6 +12698,9 @@ TOML_IMPL_NAMESPACE_START
|
|||
if (*cp != traits::prefix_codepoint)
|
||||
set_error_and_return_default("expected '"sv, traits::prefix, "', saw '"sv, to_sv(*cp), "'"sv);
|
||||
advance_and_return_if_error_or_eof({});
|
||||
|
||||
if (!traits::is_digit(*cp))
|
||||
set_error_and_return_default("expected digit, saw '"sv, to_sv(*cp), "'"sv);
|
||||
}
|
||||
|
||||
// consume value chars
|
||||
|
@ -13010,7 +13013,6 @@ TOML_IMPL_NAMESPACE_START
|
|||
node_ptr parse_inline_table();
|
||||
|
||||
TOML_NODISCARD
|
||||
TOML_NEVER_INLINE
|
||||
node_ptr parse_value_known_prefixes()
|
||||
{
|
||||
return_if_error({});
|
||||
|
@ -13114,8 +13116,8 @@ TOML_IMPL_NAMESPACE_START
|
|||
begins_digit = 1 << 13,
|
||||
begins_zero = 1 << 14,
|
||||
signs_msk = has_plus | has_minus,
|
||||
bzero_msk = begins_zero | has_digits,
|
||||
bdigit_msk = begins_digit | has_digits,
|
||||
bdigit_msk = has_digits | begins_digit,
|
||||
bzero_msk = bdigit_msk | begins_zero,
|
||||
};
|
||||
value_traits traits = has_nothing;
|
||||
const auto has_any = [&](auto t) noexcept { return (traits & t) != has_nothing; };
|
||||
|
@ -13125,7 +13127,11 @@ TOML_IMPL_NAMESPACE_START
|
|||
// examine the first character to get the 'begins with' traits
|
||||
// (good fail-fast opportunity; all the remaining types begin with numeric digits or signs)
|
||||
if (is_decimal_digit(*cp))
|
||||
add_trait(*cp == U'0' ? begins_zero : begins_digit);
|
||||
{
|
||||
add_trait(begins_digit);
|
||||
if (*cp == U'0')
|
||||
add_trait(begins_zero);
|
||||
}
|
||||
else if (is_match(*cp, U'+', U'-'))
|
||||
add_trait(begins_sign);
|
||||
else
|
||||
|
@ -13210,8 +13216,12 @@ TOML_IMPL_NAMESPACE_START
|
|||
return_if_error({});
|
||||
|
||||
// force further scanning if this could have been a date-time with a space instead of a T
|
||||
if (char_count == 10u && traits == (bdigit_msk | has_minus) && chars[4] == U'-' && chars[7] == U'-'
|
||||
&& !is_eof() && *cp == U' ')
|
||||
if (char_count == 10u //
|
||||
&& (traits | begins_zero) == (bzero_msk | has_minus) //
|
||||
&& chars[4] == U'-' //
|
||||
&& chars[7] == U'-' //
|
||||
&& !is_eof() //
|
||||
&& *cp == U' ')
|
||||
{
|
||||
const auto pre_advance_count = advance_count;
|
||||
const auto pre_scan_traits = traits;
|
||||
|
@ -13255,7 +13265,7 @@ TOML_IMPL_NAMESPACE_START
|
|||
// the only valid value type is an integer.
|
||||
if (char_count == 1u)
|
||||
{
|
||||
if (has_any(begins_zero | begins_digit))
|
||||
if (has_any(begins_digit))
|
||||
{
|
||||
val.reset(new value{ static_cast<int64_t>(chars[0] - U'0') });
|
||||
advance(); // skip the digit
|
||||
|
@ -13301,7 +13311,7 @@ TOML_IMPL_NAMESPACE_START
|
|||
val.reset(new value{ i });
|
||||
val->ref_cast<int64_t>().flags(flags);
|
||||
}
|
||||
else if (has_any(has_e) || (has_any(begins_zero | begins_digit) && chars[1] == U'.'))
|
||||
else if (has_any(has_e) || (has_any(begins_digit) && chars[1] == U'.'))
|
||||
val.reset(new value{ parse_float() });
|
||||
else if (has_any(begins_sign))
|
||||
{
|
||||
|
@ -14403,7 +14413,7 @@ TOML_PUSH_WARNINGS;
|
|||
|
||||
TOML_IMPL_NAMESPACE_START
|
||||
{
|
||||
enum class formatted_string_traits : unsigned
|
||||
enum class TOML_CLOSED_FLAGS_ENUM formatted_string_traits : unsigned
|
||||
{
|
||||
none,
|
||||
line_breaks = 1u << 0, // \n
|
||||
|
|
Loading…
Reference in New Issue