diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | .travis.yml | 5 | ||||
-rw-r--r-- | strutil_test.cc | 48 |
3 files changed, 54 insertions, 1 deletions
@@ -11,8 +11,10 @@ repo/maloader/ testcase_parse_benchmark_test.go bench-old.out bench-new.out +find_test ninja_test string_piece_test +strutil_bench strutil_test go_src_stamp version.cc diff --git a/.travis.yml b/.travis.yml index f045dd3..2fd6fa8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,10 @@ before_script: - sudo apt-get install -y libstdc++-4.8-dev clang-3.5 ninja-build realpath script: - - make -j4 ckati + - make -j4 ckati ckati_tests - ruby runtest.rb -c - ruby runtest.rb -c -n - ruby runtest.rb -c -n -a + - ./ninja_test + - ./string_piece_test + - ./strutil_test 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); } |