Merge pull request #116 from AlexSmithEtas/fix-issue-115-null-c-string-derefs

Avoid dereferencing NULL C-strings
Fixes #115
This commit is contained in:
Alexander Grund 2023-01-03 18:53:40 +01:00 committed by GitHub
commit fa29eec0bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 37 additions and 2 deletions

View file

@ -39,7 +39,12 @@ class matcher<const char*, const char*>
{ {
public: public:
explicit matcher(const char* expected) : expected_(expected) {} explicit matcher(const char* expected) : expected_(expected) {}
bool operator()(const char* actual) { return std::strcmp(actual, expected_) == 0; } bool operator()(const char* actual)
{
if(!actual || !expected_)
return actual == expected_;
return std::strcmp(actual, expected_) == 0;
}
friend std::ostream& operator<<(std::ostream& s, const matcher& m) { return s << mock::format(m.expected_); } friend std::ostream& operator<<(std::ostream& s, const matcher& m) { return s << mock::format(m.expected_); }
private: private:

View file

@ -106,7 +106,13 @@ namespace detail {
{ {
s << '"' << str << '"'; s << '"' << str << '"';
} }
inline void serialize(stream& s, const char* const str) { s << '"' << str << '"'; } inline void serialize(stream& s, const char* const str)
{
if(str)
s << '"' << str << '"';
else
s << "nullptr";
}
inline void serialize(stream& s, unsigned char c) { s << static_cast<int>(c); } inline void serialize(stream& s, unsigned char c) { s << static_cast<int>(c); }
} // namespace detail } // namespace detail
} // namespace mock } // namespace mock

View file

@ -80,6 +80,15 @@ BOOST_AUTO_TEST_CASE(equal_constraint_deref)
} }
} }
BOOST_AUTO_TEST_CASE(equal_null_c_string)
{
const char* const null_str = nullptr;
BOOST_CHECK(mock::equal(null_str).c_(null_str));
BOOST_CHECK(!mock::equal(null_str).c_("non-null string"));
BOOST_CHECK(!mock::equal("non-null-string").c_(null_str));
}
BOOST_AUTO_TEST_CASE(same_constraint) BOOST_AUTO_TEST_CASE(same_constraint)
{ {
{ {

View file

@ -89,6 +89,13 @@ BOOST_AUTO_TEST_CASE(strings_are_serialized_with_double_quotes)
BOOST_CHECK_EQUAL("\"string\"", to_string(std::string("string"))); BOOST_CHECK_EQUAL("\"string\"", to_string(std::string("string")));
} }
BOOST_AUTO_TEST_CASE(null_c_strings_are_serialized_to_nullptr)
{
const char* const null_str = nullptr;
BOOST_CHECK_EQUAL("nullptr", to_string(null_str));
BOOST_CHECK_EQUAL("\"nullptr\"", to_string("nullptr"));
}
namespace { namespace {
struct non_serializable struct non_serializable
{}; {};

View file

@ -75,6 +75,14 @@ BOOST_FIXTURE_TEST_CASE(const_char_pointer_and_std_string_can_be_compared, fixtu
BOOST_CHECK(!match(std::string("different text"), actual)); BOOST_CHECK(!match(std::string("different text"), actual));
} }
BOOST_AUTO_TEST_CASE(null_const_char_pointers_can_be_compared)
{
const char* const null_str = nullptr;
BOOST_CHECK(match(null_str, null_str));
BOOST_CHECK(!match(null_str, "non-null string"));
BOOST_CHECK(!match("non-null string", null_str));
}
namespace { namespace {
template<typename T> template<typename T>
std::string serialize(const T& t) std::string serialize(const T& t)