aboutsummaryrefslogtreecommitdiffstats
path: root/strutil_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'strutil_test.cc')
-rw-r--r--strutil_test.cc48
1 files changed, 48 insertions, 0 deletions
diff --git a/strutil_test.cc b/strutil_test.cc
index a89786f..d7290d1 100644
--- a/strutil_test.cc
+++ b/strutil_test.cc
@@ -17,6 +17,8 @@
#include "strutil.h"
#include <assert.h>
+#include <sys/mman.h>
+#include <unistd.h>
#include <string>
#include <vector>
@@ -138,6 +140,50 @@ void TestFindEndOfLine() {
ASSERT_EQ(FindEndOfLine(StringPiece(buf, 2), 0, &lf_cnt), 2);
}
+// Take a string, and copy it into an allocated buffer where
+// the byte immediately after the null termination character
+// is read protected. Useful for testing, but doesn't support
+// freeing the allocated pages.
+const char* CreateProtectedString(const char* str) {
+ int pagesize = sysconf(_SC_PAGE_SIZE);
+ void *buffer;
+ char *buffer_str;
+
+ // Allocate two pages of memory
+ if (posix_memalign(&buffer, pagesize, pagesize * 2) != 0) {
+ perror("posix_memalign failed");
+ assert(false);
+ }
+
+ // Make the second page unreadable
+ buffer_str = (char*)buffer + pagesize;
+ if (mprotect(buffer_str, pagesize, PROT_NONE) != 0) {
+ perror("mprotect failed");
+ assert(false);
+ }
+
+ // Then move the test string into the very end of the first page
+ buffer_str -= strlen(str) + 1;
+ strcpy(buffer_str, str);
+
+ return buffer_str;
+}
+
+void TestWordScannerInvalidAccess() {
+ vector<StringPiece> ss;
+ for (StringPiece tok : WordScanner(CreateProtectedString("0123 456789"))) {
+ ss.push_back(tok);
+ }
+ assert(ss.size() == 2LU);
+ ASSERT_EQ(ss[0], "0123");
+ ASSERT_EQ(ss[1], "56789");
+}
+
+void TestFindEndOfLineInvalidAccess() {
+ size_t lf_cnt = 0;
+ ASSERT_EQ(FindEndOfLine(CreateProtectedString("a\\"), 0, &lf_cnt), 2);
+}
+
} // namespace
int main() {
@@ -150,5 +196,7 @@ int main() {
TestNormalizePath();
TestEscapeShell();
TestFindEndOfLine();
+ TestWordScannerInvalidAccess();
+ TestFindEndOfLineInvalidAccess();
assert(!g_failed);
}