mirror of
https://github.com/fmtlib/fmt.git
synced 2025-02-22 15:39:50 +00:00
Diagnose invalid precision
This commit is contained in:
parent
707d7d923a
commit
a80d668a52
@ -2323,7 +2323,7 @@ template <typename Char> struct dynamic_spec_id_handler {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Parses [integer | "{" [arg_id] "}"].
|
// Parses integer | "{" [arg_id] "}".
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
FMT_CONSTEXPR auto parse_dynamic_spec(const Char* begin, const Char* end,
|
FMT_CONSTEXPR auto parse_dynamic_spec(const Char* begin, const Char* end,
|
||||||
int& value, arg_ref<Char>& ref,
|
int& value, arg_ref<Char>& ref,
|
||||||
@ -2332,24 +2332,24 @@ FMT_CONSTEXPR auto parse_dynamic_spec(const Char* begin, const Char* end,
|
|||||||
FMT_ASSERT(begin != end, "");
|
FMT_ASSERT(begin != end, "");
|
||||||
if ('0' <= *begin && *begin <= '9') {
|
if ('0' <= *begin && *begin <= '9') {
|
||||||
int val = parse_nonnegative_int(begin, end, -1);
|
int val = parse_nonnegative_int(begin, end, -1);
|
||||||
if (val != -1)
|
if (val == -1) report_error("number is too big");
|
||||||
value = val;
|
value = val;
|
||||||
else
|
} else {
|
||||||
report_error("number is too big");
|
if (*begin == '{') {
|
||||||
} else if (*begin == '{') {
|
++begin;
|
||||||
++begin;
|
if (begin != end) {
|
||||||
if (begin != end) {
|
Char c = *begin;
|
||||||
Char c = *begin;
|
if (c == '}' || c == ':') {
|
||||||
if (c == '}' || c == ':') {
|
int id = ctx.next_arg_id();
|
||||||
int id = ctx.next_arg_id();
|
ref = arg_ref<Char>(id);
|
||||||
ref = arg_ref<Char>(id);
|
ctx.check_dynamic_spec(id);
|
||||||
ctx.check_dynamic_spec(id);
|
} else {
|
||||||
} else {
|
begin =
|
||||||
begin =
|
parse_arg_id(begin, end, dynamic_spec_id_handler<Char>{ctx, ref});
|
||||||
parse_arg_id(begin, end, dynamic_spec_id_handler<Char>{ctx, ref});
|
}
|
||||||
}
|
}
|
||||||
|
if (begin != end && *begin == '}') return ++begin;
|
||||||
}
|
}
|
||||||
if (begin != end && *begin == '}') return ++begin;
|
|
||||||
report_error("invalid format string");
|
report_error("invalid format string");
|
||||||
}
|
}
|
||||||
return begin;
|
return begin;
|
||||||
@ -2361,11 +2361,9 @@ FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end,
|
|||||||
basic_format_parse_context<Char>& ctx)
|
basic_format_parse_context<Char>& ctx)
|
||||||
-> const Char* {
|
-> const Char* {
|
||||||
++begin;
|
++begin;
|
||||||
if (begin == end || *begin == '}') {
|
if (begin != end) begin = parse_dynamic_spec(begin, end, value, ref, ctx);
|
||||||
report_error("invalid precision");
|
else report_error("invalid precision");
|
||||||
return begin;
|
return begin;
|
||||||
}
|
|
||||||
return parse_dynamic_spec(begin, end, value, ref, ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class state { start, align, sign, hash, zero, width, precision, locale };
|
enum class state { start, align, sign, hash, zero, width, precision, locale };
|
||||||
|
@ -2251,8 +2251,11 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
|
|||||||
it = detail::parse_align(it, end, specs_);
|
it = detail::parse_align(it, end, specs_);
|
||||||
if (it == end) return it;
|
if (it == end) return it;
|
||||||
|
|
||||||
it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
|
Char c = *it;
|
||||||
if (it == end) return it;
|
if ((c >= '0' && c <= '9') || c == '{') {
|
||||||
|
it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
|
||||||
|
if (it == end) return it;
|
||||||
|
}
|
||||||
|
|
||||||
auto checker = detail::chrono_format_checker();
|
auto checker = detail::chrono_format_checker();
|
||||||
if (*it == '.') {
|
if (*it == '.') {
|
||||||
@ -2410,8 +2413,11 @@ template <typename Char> struct formatter<std::tm, Char> {
|
|||||||
it = detail::parse_align(it, end, specs_);
|
it = detail::parse_align(it, end, specs_);
|
||||||
if (it == end) return it;
|
if (it == end) return it;
|
||||||
|
|
||||||
it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
|
Char c = *it;
|
||||||
if (it == end) return it;
|
if ((c >= '0' && c <= '9') || c == '{') {
|
||||||
|
it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
|
||||||
|
if (it == end) return it;
|
||||||
|
}
|
||||||
|
|
||||||
end = detail::parse_chrono_format(it, end, detail::tm_format_checker());
|
end = detail::parse_chrono_format(it, end, detail::tm_format_checker());
|
||||||
// Replace the default format_str only if the new spec is not empty.
|
// Replace the default format_str only if the new spec is not empty.
|
||||||
|
@ -129,7 +129,9 @@ template <typename Char> struct formatter<std::filesystem::path, Char> {
|
|||||||
it = detail::parse_align(it, end, specs_);
|
it = detail::parse_align(it, end, specs_);
|
||||||
if (it == end) return it;
|
if (it == end) return it;
|
||||||
|
|
||||||
it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
|
Char c = *it;
|
||||||
|
if ((c >= '0' && c <= '9') || c == '{')
|
||||||
|
it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
|
||||||
if (it != end && *it == '?') {
|
if (it != end && *it == '?') {
|
||||||
debug_ = true;
|
debug_ = true;
|
||||||
++it;
|
++it;
|
||||||
|
@ -945,7 +945,7 @@ TEST(format_test, precision) {
|
|||||||
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:."), 0.0), format_error,
|
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:."), 0.0), format_error,
|
||||||
"invalid precision");
|
"invalid precision");
|
||||||
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.}"), 0.0), format_error,
|
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.}"), 0.0), format_error,
|
||||||
"invalid precision");
|
"invalid format string");
|
||||||
|
|
||||||
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2"), 0), format_error,
|
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2"), 0), format_error,
|
||||||
"invalid format specifier");
|
"invalid format specifier");
|
||||||
@ -1066,6 +1066,8 @@ TEST(format_test, precision) {
|
|||||||
EXPECT_THROW_MSG(
|
EXPECT_THROW_MSG(
|
||||||
(void)fmt::format("{:.2147483646f}", -2.2121295195081227E+304),
|
(void)fmt::format("{:.2147483646f}", -2.2121295195081227E+304),
|
||||||
format_error, "number is too big");
|
format_error, "number is too big");
|
||||||
|
EXPECT_THROW_MSG((void)fmt::format(runtime("{:.f}"), 42.0), format_error,
|
||||||
|
"invalid format string");
|
||||||
|
|
||||||
EXPECT_EQ(fmt::format("{0:.2}", "str"), "st");
|
EXPECT_EQ(fmt::format("{0:.2}", "str"), "st");
|
||||||
EXPECT_EQ(fmt::format("{0:.5}", "вожыкі"), "вожык");
|
EXPECT_EQ(fmt::format("{0:.5}", "вожыкі"), "вожык");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user