Skip to content

Commit 2d7b357

Browse files
committed
Fix condition to treat an id as alphanumeric string
An id is considered an alphanumeric string if it contains a non-empty sequence of alphanumeric characters followed by one or more null characters. Fixed unit tests accordingly.
1 parent 5ea78de commit 2d7b357

File tree

2 files changed

+66
-9
lines changed

2 files changed

+66
-9
lines changed

src/id.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,34 @@ std::string wsrep::id::to_string() const
5757
return os.str();
5858
}
5959

60+
61+
/*
62+
* If the buffer pointed by ptr contains only alphanumeric chars followed by
63+
* one or more null terminators, consider it a valid alphanumeric string.
64+
*
65+
* A string starting with null is not an alphanumeric string.
66+
*/
67+
static bool is_alphanumeric_string(const char* ptr, size_t size)
68+
{
69+
if (size == 0)
70+
return false;
71+
if (ptr[0] == '\0')
72+
return false;
73+
const char* first_not_alphanumeric = std::find_if_not(
74+
ptr, ptr + size, [](char c) { return ::isalnum(c); });
75+
if (static_cast<size_t>(std::distance(ptr, first_not_alphanumeric)) == size)
76+
return false;
77+
return std::all_of(first_not_alphanumeric, ptr + size,
78+
[](char c) { return (c == '\0'); });
79+
}
80+
6081
std::ostream& wsrep::operator<<(std::ostream& os, const wsrep::id& id)
6182
{
6283
const char* ptr(static_cast<const char*>(id.data()));
6384
size_t size(id.size());
64-
if (static_cast<size_t>(
65-
std::count_if(ptr, ptr + size,
66-
[](char c) { return (::isalnum(c) || c == '\0'); }))
67-
== size)
85+
/* If the buffer pointed by ptr contains only alphanumeric chars followed by
86+
* one or more null terminators, return the string. */
87+
if (is_alphanumeric_string(ptr, size))
6888
{
6989
return (os << std::string(ptr, ::strnlen(ptr, size)));
7090
}

test/id_test.cpp

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ BOOST_AUTO_TEST_CASE(id_test_uuid)
3333
wsrep::id id(uuid_str);
3434
std::ostringstream os;
3535
os << id;
36-
BOOST_REQUIRE(uuid_str == os.str());
36+
BOOST_REQUIRE_EQUAL(uuid_str, os.str());
3737
}
3838

3939
BOOST_AUTO_TEST_CASE(id_test_string)
@@ -42,16 +42,19 @@ BOOST_AUTO_TEST_CASE(id_test_string)
4242
wsrep::id id(id_str);
4343
std::ostringstream os;
4444
os << id;
45-
BOOST_REQUIRE(id_str == os.str());
45+
BOOST_REQUIRE_EQUAL(id_str, os.str());
4646
}
4747

4848
BOOST_AUTO_TEST_CASE(id_test_string_max)
4949
{
50-
std::string id_str("1234567890123456");
50+
std::string id_str("1234"
51+
"5678"
52+
"9012"
53+
"3456");
5154
wsrep::id id(id_str);
5255
std::ostringstream os;
5356
os << id;
54-
BOOST_REQUIRE(id_str == os.str());
57+
BOOST_REQUIRE_EQUAL(os.str(), "31323334-3536-3738-3930-313233343536");
5558
}
5659

5760
BOOST_AUTO_TEST_CASE(id_test_string_too_long)
@@ -67,7 +70,7 @@ BOOST_AUTO_TEST_CASE(id_test_binary)
6770
wsrep::id id(data, sizeof(data));
6871
std::ostringstream os;
6972
os << id;
70-
BOOST_REQUIRE(os.str() == "01020304-0506-0708-0900-010203040506");
73+
BOOST_REQUIRE_EQUAL(os.str(), "01020304-0506-0708-0900-010203040506");
7174
}
7275

7376
BOOST_AUTO_TEST_CASE(id_test_binary_too_long)
@@ -76,3 +79,37 @@ BOOST_AUTO_TEST_CASE(id_test_binary_too_long)
7679
BOOST_REQUIRE_EXCEPTION(wsrep::id id(data, sizeof(data)),
7780
wsrep::runtime_error, exception_check);;
7881
}
82+
83+
BOOST_AUTO_TEST_CASE(id_test_binary_all_alphanumeric)
84+
{
85+
char data[16] = {'a', 'a', 'a', 'a',
86+
'a', 'a', 'a', 'a',
87+
'a', 'a', 'a', 'a',
88+
'a', 'a', 'a', 'a'};
89+
wsrep::id id(data, sizeof(data));
90+
std::ostringstream os;
91+
os << id;
92+
/* Value of 'a' is 97 in ASCII, which is 0x61 in hex. */
93+
BOOST_REQUIRE_EQUAL(os.str(), "61616161-6161-6161-6161-616161616161");
94+
}
95+
96+
BOOST_AUTO_TEST_CASE(id_test_binary_all_except_middle_alphanumeric)
97+
{
98+
char data[16] = {'a', 'a', 'a', 'a',
99+
'a', 'a', 'a', 'a',
100+
'a', 'a', '\0', 'a',
101+
'a', 'a', 'a', 'a'};
102+
wsrep::id id(data, sizeof(data));
103+
std::ostringstream os;
104+
os << id;
105+
BOOST_REQUIRE_EQUAL(os.str(), "61616161-6161-6161-6161-006161616161");
106+
}
107+
108+
BOOST_AUTO_TEST_CASE(id_test_null)
109+
{
110+
char data[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
111+
wsrep::id id(data, sizeof(data));
112+
std::ostringstream os;
113+
os << id;
114+
BOOST_REQUIRE_EQUAL(os.str(), "00000000-0000-0000-0000-000000000000");
115+
}

0 commit comments

Comments
 (0)