Skip to content

Formatting string-like custom types with an equals sign immediately following closing brace throws an exception #750

Closed
@mwinterb

Description

@mwinterb

Assuming this type and formatter:

class StringAnswer {};
namespace fmt
{
template<>
struct formatter<StringAnswer> : formatter<string_view> {
  auto format(StringAnswer, fmt::format_context &ctx) -> decltype(ctx.out()) {
    string_view fourtwo("42");
    return formatter<string_view>::format(fourtwo, ctx);
  }
};
}

And a format call of fmt::format("{}=", StringAnswer());.
In parse_format_specs, it points to }=. For the first iteration of "Parse fill and alignment", p will point to =. The = is treated as an ALIGN_NUMERIC alignment specifier, and the specs_checker handler will throw an exception when on_align is called because the type is not a numeric type.

Adding this check

if (*it == '}')
  return it;

to the very beginning of parse_format_specs fixes this issue and all existing tests pass. It seems like it doesn't (mostly) change the behavior in other scenarios, but I'm puzzled by this test, because I don't see how c could have a value of } except in cases like this. And since my proposed change just seems like such an obvious check since it seems like it would have a high rate of being true most of the time, I feel like I must be missing something. Otherwise this would have been a PR and not an issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions