mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-29 18:27:40 +02:00
Fix chrono formatting with invalid argument id (#1132)
This commit is contained in:
@ -585,18 +585,20 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
typedef typename basic_parse_context<Char>::iterator iterator;
|
||||||
formatter() : spec(), precision(-1) {}
|
struct parse_range {
|
||||||
|
iterator begin;
|
||||||
|
iterator end;
|
||||||
|
};
|
||||||
|
|
||||||
FMT_CONSTEXPR auto parse(basic_parse_context<Char>& ctx)
|
FMT_CONSTEXPR parse_range do_parse(basic_parse_context<Char>& ctx) {
|
||||||
-> decltype(ctx.begin()) {
|
|
||||||
auto begin = ctx.begin(), end = ctx.end();
|
auto begin = ctx.begin(), end = ctx.end();
|
||||||
if (begin == end) return begin;
|
if (begin == end) return {begin, end};
|
||||||
spec_handler handler{*this, ctx, format_str};
|
spec_handler handler{*this, ctx, format_str};
|
||||||
begin = internal::parse_align(begin, end, handler);
|
begin = internal::parse_align(begin, end, handler);
|
||||||
if (begin == end) return begin;
|
if (begin == end) return {begin, end};
|
||||||
begin = internal::parse_width(begin, end, handler);
|
begin = internal::parse_width(begin, end, handler);
|
||||||
if (begin == end) return begin;
|
if (begin == end) return {begin, end};
|
||||||
if (*begin == '.') {
|
if (*begin == '.') {
|
||||||
if (std::is_floating_point<Rep>::value)
|
if (std::is_floating_point<Rep>::value)
|
||||||
begin = internal::parse_precision(begin, end, handler);
|
begin = internal::parse_precision(begin, end, handler);
|
||||||
@ -604,9 +606,18 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
|
|||||||
handler.on_error("precision not allowed for this argument type");
|
handler.on_error("precision not allowed for this argument type");
|
||||||
}
|
}
|
||||||
end = parse_chrono_format(begin, end, internal::chrono_format_checker());
|
end = parse_chrono_format(begin, end, internal::chrono_format_checker());
|
||||||
format_str =
|
return {begin, end};
|
||||||
basic_string_view<Char>(&*begin, internal::to_unsigned(end - begin));
|
}
|
||||||
return end;
|
|
||||||
|
public:
|
||||||
|
formatter() : spec(), precision(-1) {}
|
||||||
|
|
||||||
|
FMT_CONSTEXPR auto parse(basic_parse_context<Char>& ctx)
|
||||||
|
-> decltype(ctx.begin()) {
|
||||||
|
auto range = do_parse(ctx);
|
||||||
|
format_str = basic_string_view<Char>(
|
||||||
|
&*range.begin, internal::to_unsigned(range.end - range.begin));
|
||||||
|
return range.end;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FormatContext>
|
template <typename FormatContext>
|
||||||
|
@ -296,4 +296,9 @@ TEST(ChronoTest, FormatFullSpecsQq) {
|
|||||||
EXPECT_EQ("*1.2340 ms*", fmt::format("{:*^11.4%Q %q}", dms(1.234)));
|
EXPECT_EQ("*1.2340 ms*", fmt::format("{:*^11.4%Q %q}", dms(1.234)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ChronoTest, InvalidWidthId) {
|
||||||
|
EXPECT_THROW(fmt::format("{:{o}", std::chrono::seconds(0)),
|
||||||
|
fmt::format_error);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // FMT_STATIC_THOUSANDS_SEPARATOR
|
#endif // FMT_STATIC_THOUSANDS_SEPARATOR
|
||||||
|
Reference in New Issue
Block a user