diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index b65bdfad..53563860 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -585,18 +585,20 @@ struct formatter, Char> { } }; - public: - formatter() : spec(), precision(-1) {} + typedef typename basic_parse_context::iterator iterator; + struct parse_range { + iterator begin; + iterator end; + }; - FMT_CONSTEXPR auto parse(basic_parse_context& ctx) - -> decltype(ctx.begin()) { + FMT_CONSTEXPR parse_range do_parse(basic_parse_context& ctx) { 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}; 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); - if (begin == end) return begin; + if (begin == end) return {begin, end}; if (*begin == '.') { if (std::is_floating_point::value) begin = internal::parse_precision(begin, end, handler); @@ -604,9 +606,18 @@ struct formatter, Char> { handler.on_error("precision not allowed for this argument type"); } end = parse_chrono_format(begin, end, internal::chrono_format_checker()); - format_str = - basic_string_view(&*begin, internal::to_unsigned(end - begin)); - return end; + return {begin, end}; + } + + public: + formatter() : spec(), precision(-1) {} + + FMT_CONSTEXPR auto parse(basic_parse_context& ctx) + -> decltype(ctx.begin()) { + auto range = do_parse(ctx); + format_str = basic_string_view( + &*range.begin, internal::to_unsigned(range.end - range.begin)); + return range.end; } template diff --git a/test/chrono-test.cc b/test/chrono-test.cc index 40d34235..bb546f7b 100644 --- a/test/chrono-test.cc +++ b/test/chrono-test.cc @@ -296,4 +296,9 @@ TEST(ChronoTest, FormatFullSpecsQq) { 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