unittest: harden string comparison
std::string::compare((char*)nullptr) crashes circa gcc 4.8 in call to strlen(nullptr).
This commit is contained in:
+23
-2
@@ -146,8 +146,22 @@ testCase testNotEq(const char *sLHS, const LHS& lhs, const char *sRHS, const RHS
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct as_str {
|
||||
static const char* op(const T& v) { return v; }
|
||||
};
|
||||
template<> struct as_str<std::string> {
|
||||
static const char* op(const std::string& v) { return v.c_str(); }
|
||||
};
|
||||
template<> struct as_str<const std::string> {
|
||||
static const char* op(const std::string& v) { return v.c_str(); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
const char* asStr(const T& v) { return as_str<T>::op(v); }
|
||||
|
||||
PVXS_API
|
||||
testCase _testStrEq(const char *sLHS, const std::string& lhs, const char *sRHS, const std::string& rhs);
|
||||
testCase _testStrTest(unsigned op, const char *sLHS, const char* lhs, const char *sRHS, const char* rhs);
|
||||
|
||||
PVXS_API
|
||||
testCase _testStrMatch(const char *spat, const std::string& pat, const char *sstr, const std::string& str);
|
||||
@@ -263,7 +277,14 @@ testCase testThrowsMatch(const std::string& expr, FN fn)
|
||||
//! Evaluates to a pvxs::testCase
|
||||
//! Functionally equivalent to testEq() with two std::string instances.
|
||||
//! Prints diff-like output which is friendlier to multi-line strings.
|
||||
#define testStrEq(LHS, RHS) ::pvxs::detail::_testStrEq(#LHS, LHS, #RHS, RHS)
|
||||
#define testStrEq(LHS, RHS) ::pvxs::detail::_testStrTest(1, #LHS, ::pvxs::detail::asStr(LHS), #RHS, ::pvxs::detail::asStr(RHS))
|
||||
|
||||
//! Macro which asserts inequality between LHS and RHS.
|
||||
//! Evaluates to a pvxs::testCase
|
||||
//! Functionally equivalent to testNotEq() with two std::string instances.
|
||||
//! Prints diff-like output which is friendlier to multi-line strings.
|
||||
//! @since UNRELEASED
|
||||
#define testStrNotEq(LHS, RHS) ::pvxs::detail::_testStrTest(0, #LHS, ::pvxs::detail::asStr(LHS), #RHS, ::pvxs::detail::asStr(RHS))
|
||||
|
||||
//! Macro which asserts that STR matches the regular expression EXPR
|
||||
//! Evaluates to a pvxs::testCase
|
||||
|
||||
+13
-3
@@ -118,10 +118,20 @@ size_t findNextLine(const std::string& s, size_t pos=0u)
|
||||
return next;
|
||||
}
|
||||
|
||||
testCase _testStrEq(const char *sLHS, const std::string& lhs, const char *sRHS, const std::string& rhs)
|
||||
testCase _testStrTest(unsigned op, const char *sLHS, const char* rlhs, const char *sRHS, const char* rrhs)
|
||||
{
|
||||
testCase ret(lhs==rhs);
|
||||
ret<<sLHS<<" == "<<sRHS<<"\n";
|
||||
bool eq;
|
||||
if(rlhs==rrhs) // same string. handles NULL==NULL
|
||||
eq = true;
|
||||
else if(!rlhs ^ !rrhs) // one NULL
|
||||
eq = false;
|
||||
else
|
||||
eq = strcmp(rlhs, rrhs)==0;
|
||||
testCase ret(eq==op);
|
||||
ret<<sLHS<<(op ? " == " : " != ")<<sRHS<<"\n";
|
||||
|
||||
std::string lhs(rlhs ? rlhs : "<null>");
|
||||
std::string rhs(rrhs ? rrhs : "<null>");
|
||||
|
||||
size_t posL=0u, posR=0u;
|
||||
|
||||
|
||||
+22
-1
@@ -182,16 +182,37 @@ void testAccount()
|
||||
}
|
||||
}
|
||||
|
||||
void testTestEq()
|
||||
{
|
||||
testShow()<<__func__;
|
||||
|
||||
testStrNotEq((char*)nullptr, std::string());
|
||||
testStrNotEq(std::string(), (char*)nullptr);
|
||||
testStrEq((char*)nullptr, (char*)nullptr);
|
||||
testStrEq(std::string(), std::string());
|
||||
|
||||
testStrEq("hello", "hello");
|
||||
testStrEq("hello", std::string("hello"));
|
||||
testStrEq(std::string("hello"), "hello");
|
||||
testStrEq(std::string("hello"), std::string("hello"));
|
||||
|
||||
testStrNotEq("hello", "world");
|
||||
testStrNotEq("hello", std::string("world"));
|
||||
testStrNotEq(std::string("hello"), "world");
|
||||
testStrNotEq(std::string("hello"), std::string("world"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MAIN(testutil)
|
||||
{
|
||||
testPlan(12);
|
||||
testPlan(24);
|
||||
testTrue(version_abi_check())<<" 0x"<<std::hex<<PVXS_VERSION<<" ~= 0x"<<std::hex<<PVXS_ABI_VERSION;
|
||||
testServerGUID();
|
||||
testFill();
|
||||
testSpam();
|
||||
testSpamMany();
|
||||
testAccount();
|
||||
testTestEq();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user