Disable unsafe implicit conversion to std::string (#729)

This commit is contained in:
Victor Zverovich 2018-05-19 07:14:13 -07:00
parent d2bf93fe22
commit d940fa679c
4 changed files with 13 additions and 15 deletions

View File

@ -629,8 +629,9 @@ inline typename std::enable_if<
template <typename C, typename T, typename Char = typename C::char_type> template <typename C, typename T, typename Char = typename C::char_type>
inline typename std::enable_if< inline typename std::enable_if<
!convert_to_int<T, Char>::value && !convert_to_int<T, Char>::value &&
!std::is_convertible<T, basic_string_view<Char>>::value && !std::is_convertible<T, basic_string_view<Char>>::value,
!std::is_convertible<T, std::basic_string<Char>>::value, // Implicit conversion to std::string is not handled here because it's
// unsafe: https://github.com/fmtlib/fmt/issues/729
typed_value<C, custom_type>>::type typed_value<C, custom_type>>::type
make_value(const T &val) { return val; } make_value(const T &val) { return val; }

View File

@ -9,8 +9,7 @@ set(CMAKE_REQUIRED_FLAGS ${CPP14_FLAG})
function (generate_source result fragment) function (generate_source result fragment)
set(${result} " set(${result} "
#define FMT_HEADER_ONLY 1 #define FMT_HEADER_ONLY 1
#include \"fmt/posix.h\" #include \"fmt/format.h\"
#include \"fmt/ostream.h\"
int main() { int main() {
${fragment} ${fragment}
} }
@ -58,6 +57,14 @@ expect_compile_error("fmt::format(\"{}\", L\"foo\");")
# mixing UTF-8 with UTF-16/32 can result in an invalid output. # mixing UTF-8 with UTF-16/32 can result in an invalid output.
expect_compile_error("fmt::format(L\"{}\", \"foo\");") expect_compile_error("fmt::format(L\"{}\", \"foo\");")
# Formatting a wide string with a narrow format string is forbidden.
expect_compile_error("
struct S {
operator std::string() const { return std::string(); }
};
fmt::format(\"{}\", S());
")
# Make sure that compiler features detected in the header # Make sure that compiler features detected in the header
# match the features detected in CMake. # match the features detected in CMake.
if (SUPPORTS_USER_DEFINED_LITERALS) if (SUPPORTS_USER_DEFINED_LITERALS)

View File

@ -1072,16 +1072,6 @@ TEST(FormatterTest, FormatStdStringView) {
} }
#endif #endif
struct ConvertibleToString {
std::string s;
ConvertibleToString() : s("foo") {}
operator const std::string &() const { return s; }
};
TEST(FormatterTest, FormatConvertibleToString) {
EXPECT_EQ("foo", format("{}", ConvertibleToString()));
}
struct ConvertibleToStringView { struct ConvertibleToStringView {
operator fmt::string_view() const { return "foo"; } operator fmt::string_view() const { return "foo"; }
}; };

View File

@ -402,7 +402,7 @@ TEST(UtilTest, BitCast) {
uint32_t u[2]; uint32_t u[2];
}; };
auto s = fmt::internal::bit_cast<S>(uint64_t(42)); auto s = fmt::internal::bit_cast<S>(uint64_t(42));
EXPECT_EQ(fmt::internal::bit_cast<uint64_t>(s), 42); EXPECT_EQ(fmt::internal::bit_cast<uint64_t>(s), 42u);
s = fmt::internal::bit_cast<S>(uint64_t(~0ull)); s = fmt::internal::bit_cast<S>(uint64_t(~0ull));
EXPECT_EQ(fmt::internal::bit_cast<uint64_t>(s), ~0ull); EXPECT_EQ(fmt::internal::bit_cast<uint64_t>(s), ~0ull);
} }