summaryrefslogtreecommitdiff
path: root/libutils/tests/Unicode_test.cpp
diff options
context:
space:
mode:
authorBranislav Rankov <branislav.rankov@arm.com>2017-10-12 15:08:42 +0200
committerMark Salyzyn <salyzyn@google.com>2017-10-24 10:36:00 -0700
commitbf3fff1a9ed39d005f36db43c9893697e0a006a3 (patch)
tree37ce2048faef4e49fc5b97a0abf15f5f460342ce /libutils/tests/Unicode_test.cpp
parent1c65e77e6d73b9eee13d913e0b7886c72282e67f (diff)
libutils: Fix bug in strstr16.
In the original code when target is an empty string strlen16() would start reading the memory until a "terminating null" (that is, zero) character is found. This may happen because "*target++", at line 300, would increment the pointer beyond the actual string. Signed-off-by: Branislav Rankov <branislav.rankov@arm.com> Signed-off-by: Tamas Petz <tamas.petz@arm.com> Test: libutils_tests --gtest_filter=UnicodeTest.strstr16* Change-Id: I213ffe061057c7fa8f34b68881e106a709557dcd
Diffstat (limited to 'libutils/tests/Unicode_test.cpp')
-rw-r--r--libutils/tests/Unicode_test.cpp31
1 files changed, 30 insertions, 1 deletions
diff --git a/libutils/tests/Unicode_test.cpp b/libutils/tests/Unicode_test.cpp
index d23e43a71..b92eef866 100644
--- a/libutils/tests/Unicode_test.cpp
+++ b/libutils/tests/Unicode_test.cpp
@@ -15,7 +15,11 @@
*/
#define LOG_TAG "Unicode_test"
-#include <utils/Log.h>
+
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <log/log.h>
#include <utils/Unicode.h>
#include <gtest/gtest.h>
@@ -119,6 +123,31 @@ TEST_F(UnicodeTest, strstr16EmptyTarget) {
<< "should return the original pointer";
}
+TEST_F(UnicodeTest, strstr16EmptyTarget_bug) {
+ // In the original code when target is an empty string strlen16() would
+ // start reading the memory until a "terminating null" (that is, zero)
+ // character is found. This happens because "*target++" in the original
+ // code would increment the pointer beyond the actual string.
+ void* memptr;
+ const size_t alignment = sysconf(_SC_PAGESIZE);
+ const size_t size = 2 * alignment;
+ ASSERT_EQ(posix_memalign(&memptr, alignment, size), 0);
+ // Fill allocated memory.
+ memset(memptr, 'A', size);
+ // Create a pointer to an "empty" string on the first page.
+ char16_t* const emptyString = (char16_t* const)((char*)memptr + alignment - 4);
+ *emptyString = (char16_t)0;
+ // Protect the second page to show that strstr16() violates that.
+ ASSERT_EQ(mprotect((char*)memptr + alignment, alignment, PROT_NONE), 0);
+ // Test strstr16(): when bug is present a segmentation fault is raised.
+ ASSERT_EQ(strstr16((char16_t*)memptr, emptyString), (char16_t*)memptr)
+ << "should not read beyond the first char16_t.";
+ // Reset protection of the second page
+ ASSERT_EQ(mprotect((char*)memptr + alignment, alignment, PROT_READ | PROT_WRITE), 0);
+ // Free allocated memory.
+ free(memptr);
+}
+
TEST_F(UnicodeTest, strstr16SameString) {
const char16_t* result = strstr16(kSearchString, kSearchString);
EXPECT_EQ(kSearchString, result)