Add new memchr/strrchr tests.
There are new optimizations for these functions, so adding some extra
testing for these routines.
Also, clean up the strchr test slightly with some extra comments.
Test: Ran new tests on glibc version, and on angler.
Change-Id: I41bf4e5e2c84295cc1ce9d2226ed57c2d228d7b8
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index 385fe33..0d42b05 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -1372,20 +1372,56 @@
RunCmpBufferOverreadTest(DoMemcmpTest, DoMemcmpFailTest);
}
+static void DoMemchrTest(uint8_t* buf, size_t len) {
+ if (len >= 1) {
+ int value = len % 128;
+ int search_value = (len % 128) + 1;
+ memset(buf, value, len);
+ // The buffer does not contain the search value.
+ ASSERT_EQ(nullptr, memchr(buf, search_value, len));
+ if (len >= 2) {
+ buf[0] = search_value;
+ // The search value is the first element in the buffer.
+ ASSERT_EQ(&buf[0], memchr(buf, search_value, len));
+
+ buf[0] = value;
+ buf[len - 1] = search_value;
+ // The search value is the last element in the buffer.
+ ASSERT_EQ(&buf[len - 1], memchr(buf, search_value, len));
+ }
+ }
+}
+
+TEST(STRING_TEST, memchr_align) {
+ RunSingleBufferAlignTest(MEDIUM, DoMemchrTest);
+}
+
+TEST(STRING_TEST, memchr_overread) {
+ RunSingleBufferOverreadTest(DoMemchrTest);
+}
+
static void DoStrchrTest(uint8_t* buf, size_t len) {
if (len >= 1) {
char value = 32 + (len % 96);
char search_value = 33 + (len % 96);
memset(buf, value, len - 1);
- buf[len-1] = '\0';
- ASSERT_EQ(NULL, strchr(reinterpret_cast<char*>(buf), search_value));
- ASSERT_EQ(reinterpret_cast<char*>(&buf[len-1]), strchr(reinterpret_cast<char*>(buf), '\0'));
+ buf[len - 1] = '\0';
+ // The buffer does not contain the search value.
+ ASSERT_EQ(nullptr, strchr(reinterpret_cast<char*>(buf), search_value));
+ // Search for the special '\0' character.
+ ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 1]), strchr(reinterpret_cast<char*>(buf), '\0'));
if (len >= 2) {
buf[0] = search_value;
- ASSERT_EQ(reinterpret_cast<char*>(&buf[0]), strchr(reinterpret_cast<char*>(buf), search_value));
+ // The search value is the first element in the buffer.
+ ASSERT_EQ(reinterpret_cast<char*>(&buf[0]), strchr(reinterpret_cast<char*>(buf),
+ search_value));
+
buf[0] = value;
- buf[len-2] = search_value;
- ASSERT_EQ(reinterpret_cast<char*>(&buf[len-2]), strchr(reinterpret_cast<char*>(buf), search_value));
+ buf[len - 2] = search_value;
+ // The search value is the second to last element in the buffer.
+ // The last element is the '\0' character.
+ ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 2]), strchr(reinterpret_cast<char*>(buf),
+ search_value));
}
}
}
@@ -1398,6 +1434,40 @@
RunSingleBufferOverreadTest(DoStrchrTest);
}
+static void DoStrrchrTest(uint8_t* buf, size_t len) {
+ if (len >= 1) {
+ char value = 32 + (len % 96);
+ char search_value = 33 + (len % 96);
+ memset(buf, value, len - 1);
+ buf[len - 1] = '\0';
+ // The buffer does not contain the search value.
+ ASSERT_EQ(nullptr, strrchr(reinterpret_cast<char*>(buf), search_value));
+ // Search for the special '\0' character.
+ ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 1]), strrchr(reinterpret_cast<char*>(buf), '\0'));
+ if (len >= 2) {
+ buf[0] = search_value;
+ // The search value is the first element in the buffer.
+ ASSERT_EQ(reinterpret_cast<char*>(&buf[0]), strrchr(reinterpret_cast<char*>(buf),
+ search_value));
+
+ buf[0] = value;
+ buf[len - 2] = search_value;
+ // The search value is the second to last element in the buffer.
+ // The last element is the '\0' character.
+ ASSERT_EQ(reinterpret_cast<char*>(&buf[len - 2]), strrchr(reinterpret_cast<char*>(buf),
+ search_value));
+ }
+ }
+}
+
+TEST(STRING_TEST, strrchr_align) {
+ RunSingleBufferAlignTest(MEDIUM, DoStrrchrTest);
+}
+
+TEST(STRING_TEST, strrchr_overread) {
+ RunSingleBufferOverreadTest(DoStrrchrTest);
+}
+
static void TestBasename(const char* in, const char* expected_out) {
errno = 0;
const char* out = basename(in);