mirror of
https://github.com/boostorg/static_string.git
synced 2026-08-27 15:16:43 +02:00
Fix basic_static_cstring::compare(const CharT*) for over-long inputs
compare(const CharT* s) constructed a temporary basic_static_cstring<N>
from s and delegated to the class-type overload. The constructor throws
std::length_error when traits::length(s) > N, and because compare() is
noexcept, the throw led to std::terminate():
static_cstring<3> s("abc");
s.compare("abcd"); // terminate() via noexcept throw
The free operator==() / operator!=() overloads for const CharT*, which
delegate to compare(), had the same flaw.
This commit is contained in:
@@ -363,7 +363,17 @@ public:
|
||||
|
||||
constexpr int compare(const CharT* s) const noexcept
|
||||
{
|
||||
return compare(basic_static_cstring(s));
|
||||
const size_type lhs_sz = size();
|
||||
const size_type rhs_sz = traits_type::length(s);
|
||||
const int result = traits_type::compare(data_, s, (std::min)(lhs_sz, rhs_sz));
|
||||
|
||||
return result != 0
|
||||
? result
|
||||
: lhs_sz < rhs_sz
|
||||
? -1
|
||||
: lhs_sz > rhs_sz
|
||||
? 1
|
||||
: 0;
|
||||
}
|
||||
|
||||
// Conversions.
|
||||
|
||||
@@ -443,6 +443,35 @@ testCStringComparison()
|
||||
BOOST_TEST(s.compare("abd") < 0);
|
||||
BOOST_TEST(s.compare("abb") > 0);
|
||||
}
|
||||
|
||||
// compare(const CharT*) must not throw when the argument is longer
|
||||
// than the static capacity.
|
||||
{
|
||||
static_cstring<3> s("abc");
|
||||
BOOST_TEST(s.compare("abcd") < 0);
|
||||
BOOST_TEST(s.compare("abcdefghijklmnop") < 0);
|
||||
BOOST_TEST(s.compare("abb") > 0);
|
||||
BOOST_TEST(s.compare("abd") < 0);
|
||||
BOOST_TEST(s.compare("abc") == 0);
|
||||
BOOST_TEST(s.compare("ab") > 0);
|
||||
BOOST_TEST(s.compare("") > 0);
|
||||
}
|
||||
|
||||
// Same via operator== / operator!= with an over-long C string.
|
||||
{
|
||||
static_cstring<3> s("abc");
|
||||
BOOST_TEST(!(s == "abcd"));
|
||||
BOOST_TEST(s != "abcd");
|
||||
BOOST_TEST(!("abcd" == s));
|
||||
BOOST_TEST("abcd" != s);
|
||||
}
|
||||
|
||||
// Empty static_cstring vs non-empty C string.
|
||||
{
|
||||
static_cstring<5> empty;
|
||||
BOOST_TEST(empty.compare("hello") < 0);
|
||||
BOOST_TEST(empty.compare("") == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
|
||||
Reference in New Issue
Block a user