diff options
Diffstat (limited to 'strutil_test.cc')
-rw-r--r-- | strutil_test.cc | 48 |
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); } |