mirror of
https://github.com/marzer/tomlplusplus.git
synced 2024-09-15 15:13:21 +00:00
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
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
name: Bug report
|
name: Bug report
|
||||||
about: Found a bug? Help me squash it.
|
about: Regular ol' bugs.
|
||||||
title: ''
|
title: ''
|
||||||
labels: bug
|
labels: [ "bug" ]
|
||||||
assignees: marzer
|
assignees: marzer
|
||||||
|
|
||||||
---
|
---
|
||||||
|
55
.github/ISSUE_TEMPLATE/spec_bug_report.md
vendored
Normal file
55
.github/ISSUE_TEMPLATE/spec_bug_report.md
vendored
Normal file
@ -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 missing `TOML_API` on interfaces
|
||||||
- fixed parser not correctly round-tripping the format of binary and octal integers in some cases
|
- 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 strong exception guarantee edge-cases in `toml::table` and `toml::array`
|
||||||
- fixed some incorrect unicode scalar sequence transformations (#125) (@moorereason)
|
- fixed some incorrect unicode scalar sequence transformations (#125)
|
||||||
- fixed extended-precision fractional times causing parse error instead of truncating per the spec (#127) (@moorereason)
|
- fixed a number of spec conformance issues (#127, #128, #129) (@moorereason)
|
||||||
- fixed some non-spec vertical whitespace being accepted as line breaks (#128) (@moorereason)
|
|
||||||
|
|
||||||
#### Additions:
|
#### Additions:
|
||||||
- added `operator->` to `toml::value` for class types
|
- added `operator->` to `toml::value` for class types
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
TOML_IMPL_NAMESPACE_START
|
TOML_IMPL_NAMESPACE_START
|
||||||
{
|
{
|
||||||
enum class formatted_string_traits : unsigned
|
enum class TOML_CLOSED_FLAGS_ENUM formatted_string_traits : unsigned
|
||||||
{
|
{
|
||||||
none,
|
none,
|
||||||
line_breaks = 1u << 0, // \n
|
line_breaks = 1u << 0, // \n
|
||||||
|
@ -264,7 +264,7 @@ TOML_NAMESPACE_START // abi namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Metadata associated with TOML values.
|
/// \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.
|
/// \brief None.
|
||||||
none,
|
none,
|
||||||
|
@ -2088,6 +2088,9 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
if (*cp != traits::prefix_codepoint)
|
if (*cp != traits::prefix_codepoint)
|
||||||
set_error_and_return_default("expected '"sv, traits::prefix, "', saw '"sv, to_sv(*cp), "'"sv);
|
set_error_and_return_default("expected '"sv, traits::prefix, "', saw '"sv, to_sv(*cp), "'"sv);
|
||||||
advance_and_return_if_error_or_eof({});
|
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
|
// consume value chars
|
||||||
@ -2400,7 +2403,6 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
node_ptr parse_inline_table();
|
node_ptr parse_inline_table();
|
||||||
|
|
||||||
TOML_NODISCARD
|
TOML_NODISCARD
|
||||||
TOML_NEVER_INLINE
|
|
||||||
node_ptr parse_value_known_prefixes()
|
node_ptr parse_value_known_prefixes()
|
||||||
{
|
{
|
||||||
return_if_error({});
|
return_if_error({});
|
||||||
@ -2505,8 +2507,8 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
begins_zero = 1 << 14,
|
begins_zero = 1 << 14,
|
||||||
|
|
||||||
signs_msk = has_plus | has_minus,
|
signs_msk = has_plus | has_minus,
|
||||||
bzero_msk = begins_zero | has_digits,
|
bdigit_msk = has_digits | begins_digit,
|
||||||
bdigit_msk = begins_digit | has_digits,
|
bzero_msk = bdigit_msk | begins_zero,
|
||||||
};
|
};
|
||||||
value_traits traits = has_nothing;
|
value_traits traits = has_nothing;
|
||||||
const auto has_any = [&](auto t) noexcept { return (traits & t) != 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
|
// examine the first character to get the 'begins with' traits
|
||||||
// (good fail-fast opportunity; all the remaining types begin with numeric digits or signs)
|
// (good fail-fast opportunity; all the remaining types begin with numeric digits or signs)
|
||||||
if (is_decimal_digit(*cp))
|
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'-'))
|
else if (is_match(*cp, U'+', U'-'))
|
||||||
add_trait(begins_sign);
|
add_trait(begins_sign);
|
||||||
else
|
else
|
||||||
@ -2601,8 +2607,12 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
return_if_error({});
|
return_if_error({});
|
||||||
|
|
||||||
// force further scanning if this could have been a date-time with a space instead of a T
|
// 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'-'
|
if (char_count == 10u //
|
||||||
&& !is_eof() && *cp == U' ')
|
&& (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_advance_count = advance_count;
|
||||||
const auto pre_scan_traits = traits;
|
const auto pre_scan_traits = traits;
|
||||||
@ -2646,7 +2656,7 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
// the only valid value type is an integer.
|
// the only valid value type is an integer.
|
||||||
if (char_count == 1u)
|
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') });
|
val.reset(new value{ static_cast<int64_t>(chars[0] - U'0') });
|
||||||
advance(); // skip the digit
|
advance(); // skip the digit
|
||||||
@ -2692,7 +2702,7 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
val.reset(new value{ i });
|
val.reset(new value{ i });
|
||||||
val->ref_cast<int64_t>().flags(flags);
|
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() });
|
val.reset(new value{ parse_float() });
|
||||||
else if (has_any(begins_sign))
|
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 = 0o1000000000000000000000"sv);
|
||||||
parsing_should_fail(FILE_LINE_ARGS, "val = 0b1000000000000000000000000000000000000000000000000000000000000000"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
|
// value tests
|
||||||
parse_expected_value(FILE_LINE_ARGS, "0xDEADBEEF"sv, 0xDEADBEEF);
|
parse_expected_value(FILE_LINE_ARGS, "0xDEADBEEF"sv, 0xDEADBEEF);
|
||||||
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, "\t"sv);
|
||||||
parsing_should_succeed(FILE_LINE_ARGS, "\n"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\bug_report.md" />
|
||||||
<None Include=".github\ISSUE_TEMPLATE\config.yml" />
|
<None Include=".github\ISSUE_TEMPLATE\config.yml" />
|
||||||
<None Include=".github\ISSUE_TEMPLATE\feature_request.md" />
|
<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=".github\pull_request_template.md" />
|
||||||
<None Include=".gitignore" />
|
<None Include=".gitignore" />
|
||||||
<None Include=".runsettings" />
|
<None Include=".runsettings" />
|
||||||
|
@ -217,6 +217,9 @@
|
|||||||
<None Include="include\toml++\impl\unicode.inl">
|
<None Include="include\toml++\impl\unicode.inl">
|
||||||
<Filter>include\impl</Filter>
|
<Filter>include\impl</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include=".github\ISSUE_TEMPLATE\spec_bug_report.md">
|
||||||
|
<Filter>.github</Filter>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include=".circleci">
|
<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,
|
none,
|
||||||
format_as_binary = 1,
|
format_as_binary = 1,
|
||||||
@ -12698,6 +12698,9 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
if (*cp != traits::prefix_codepoint)
|
if (*cp != traits::prefix_codepoint)
|
||||||
set_error_and_return_default("expected '"sv, traits::prefix, "', saw '"sv, to_sv(*cp), "'"sv);
|
set_error_and_return_default("expected '"sv, traits::prefix, "', saw '"sv, to_sv(*cp), "'"sv);
|
||||||
advance_and_return_if_error_or_eof({});
|
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
|
// consume value chars
|
||||||
@ -13010,7 +13013,6 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
node_ptr parse_inline_table();
|
node_ptr parse_inline_table();
|
||||||
|
|
||||||
TOML_NODISCARD
|
TOML_NODISCARD
|
||||||
TOML_NEVER_INLINE
|
|
||||||
node_ptr parse_value_known_prefixes()
|
node_ptr parse_value_known_prefixes()
|
||||||
{
|
{
|
||||||
return_if_error({});
|
return_if_error({});
|
||||||
@ -13114,8 +13116,8 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
begins_digit = 1 << 13,
|
begins_digit = 1 << 13,
|
||||||
begins_zero = 1 << 14,
|
begins_zero = 1 << 14,
|
||||||
signs_msk = has_plus | has_minus,
|
signs_msk = has_plus | has_minus,
|
||||||
bzero_msk = begins_zero | has_digits,
|
bdigit_msk = has_digits | begins_digit,
|
||||||
bdigit_msk = begins_digit | has_digits,
|
bzero_msk = bdigit_msk | begins_zero,
|
||||||
};
|
};
|
||||||
value_traits traits = has_nothing;
|
value_traits traits = has_nothing;
|
||||||
const auto has_any = [&](auto t) noexcept { return (traits & t) != 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
|
// examine the first character to get the 'begins with' traits
|
||||||
// (good fail-fast opportunity; all the remaining types begin with numeric digits or signs)
|
// (good fail-fast opportunity; all the remaining types begin with numeric digits or signs)
|
||||||
if (is_decimal_digit(*cp))
|
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'-'))
|
else if (is_match(*cp, U'+', U'-'))
|
||||||
add_trait(begins_sign);
|
add_trait(begins_sign);
|
||||||
else
|
else
|
||||||
@ -13210,8 +13216,12 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
return_if_error({});
|
return_if_error({});
|
||||||
|
|
||||||
// force further scanning if this could have been a date-time with a space instead of a T
|
// 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'-'
|
if (char_count == 10u //
|
||||||
&& !is_eof() && *cp == U' ')
|
&& (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_advance_count = advance_count;
|
||||||
const auto pre_scan_traits = traits;
|
const auto pre_scan_traits = traits;
|
||||||
@ -13255,7 +13265,7 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
// the only valid value type is an integer.
|
// the only valid value type is an integer.
|
||||||
if (char_count == 1u)
|
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') });
|
val.reset(new value{ static_cast<int64_t>(chars[0] - U'0') });
|
||||||
advance(); // skip the digit
|
advance(); // skip the digit
|
||||||
@ -13301,7 +13311,7 @@ TOML_IMPL_NAMESPACE_START
|
|||||||
val.reset(new value{ i });
|
val.reset(new value{ i });
|
||||||
val->ref_cast<int64_t>().flags(flags);
|
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() });
|
val.reset(new value{ parse_float() });
|
||||||
else if (has_any(begins_sign))
|
else if (has_any(begins_sign))
|
||||||
{
|
{
|
||||||
@ -14403,7 +14413,7 @@ TOML_PUSH_WARNINGS;
|
|||||||
|
|
||||||
TOML_IMPL_NAMESPACE_START
|
TOML_IMPL_NAMESPACE_START
|
||||||
{
|
{
|
||||||
enum class formatted_string_traits : unsigned
|
enum class TOML_CLOSED_FLAGS_ENUM formatted_string_traits : unsigned
|
||||||
{
|
{
|
||||||
none,
|
none,
|
||||||
line_breaks = 1u << 0, // \n
|
line_breaks = 1u << 0, // \n
|
||||||
|
Loading…
Reference in New Issue
Block a user