diff options
Diffstat (limited to 'lib/sanitizer_common/tests/sanitizer_libc_test.cc')
-rw-r--r-- | lib/sanitizer_common/tests/sanitizer_libc_test.cc | 108 |
1 files changed, 95 insertions, 13 deletions
diff --git a/lib/sanitizer_common/tests/sanitizer_libc_test.cc b/lib/sanitizer_common/tests/sanitizer_libc_test.cc index 3252db77653d..015e32a09e37 100644 --- a/lib/sanitizer_common/tests/sanitizer_libc_test.cc +++ b/lib/sanitizer_common/tests/sanitizer_libc_test.cc @@ -8,18 +8,21 @@ //===----------------------------------------------------------------------===// // Tests for sanitizer_libc.h. //===----------------------------------------------------------------------===// +#include <algorithm> #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_platform.h" #include "gtest/gtest.h" -#if SANITIZER_LINUX || SANITIZER_MAC -# define SANITIZER_TEST_HAS_STAT_H 1 +#if SANITIZER_WINDOWS +#define NOMINMAX +#include <windows.h> +#undef NOMINMAX +#endif +#if SANITIZER_POSIX # include <sys/stat.h> # include "sanitizer_common/sanitizer_posix.h" -#else -# define SANITIZER_TEST_HAS_STAT_H 0 #endif // A regression test for internal_memmove() implementation. @@ -57,6 +60,17 @@ struct stat_and_more { }; static void temp_file_name(char *buf, size_t bufsize, const char *prefix) { +#if SANITIZER_WINDOWS + buf[0] = '\0'; + char tmp_dir[MAX_PATH]; + if (!::GetTempPathA(MAX_PATH, tmp_dir)) + return; + // GetTempFileNameA needs a MAX_PATH buffer. + char tmp_path[MAX_PATH]; + if (!::GetTempFileNameA(tmp_dir, prefix, 0, tmp_path)) + return; + internal_strncpy(buf, tmp_path, bufsize); +#else const char *tmpdir = "/tmp"; #if SANITIZER_ANDROID // I don't know a way to query temp directory location on Android without @@ -67,10 +81,9 @@ static void temp_file_name(char *buf, size_t bufsize, const char *prefix) { #endif u32 uid = GetUid(); internal_snprintf(buf, bufsize, "%s/%s%d", tmpdir, prefix, uid); +#endif } -// FIXME: File manipulations are not yet supported on Windows -#if !defined(_WIN32) TEST(SanitizerCommon, FileOps) { const char *str1 = "qwerty"; uptr len1 = internal_strlen(str1); @@ -81,16 +94,23 @@ TEST(SanitizerCommon, FileOps) { temp_file_name(tmpfile, sizeof(tmpfile), "sanitizer_common.fileops.tmp."); fd_t fd = OpenFile(tmpfile, WrOnly); ASSERT_NE(fd, kInvalidFd); - EXPECT_EQ(len1, internal_write(fd, str1, len1)); - EXPECT_EQ(len2, internal_write(fd, str2, len2)); + uptr bytes_written = 0; + EXPECT_TRUE(WriteToFile(fd, str1, len1, &bytes_written)); + EXPECT_EQ(len1, bytes_written); + EXPECT_TRUE(WriteToFile(fd, str2, len2, &bytes_written)); + EXPECT_EQ(len2, bytes_written); CloseFile(fd); + EXPECT_TRUE(FileExists(tmpfile)); + fd = OpenFile(tmpfile, RdOnly); ASSERT_NE(fd, kInvalidFd); + +#if SANITIZER_POSIX + // The stat wrappers are posix-only. uptr fsize = internal_filesize(fd); EXPECT_EQ(len1 + len2, fsize); -#if SANITIZER_TEST_HAS_STAT_H struct stat st1, st2, st3; EXPECT_EQ(0u, internal_stat(tmpfile, &st1)); EXPECT_EQ(0u, internal_lstat(tmpfile, &st2)); @@ -108,16 +128,43 @@ TEST(SanitizerCommon, FileOps) { #endif char buf[64] = {}; - EXPECT_EQ(len1, internal_read(fd, buf, len1)); + uptr bytes_read = 0; + EXPECT_TRUE(ReadFromFile(fd, buf, len1, &bytes_read)); + EXPECT_EQ(len1, bytes_read); EXPECT_EQ(0, internal_memcmp(buf, str1, len1)); EXPECT_EQ((char)0, buf[len1 + 1]); internal_memset(buf, 0, len1); - EXPECT_EQ(len2, internal_read(fd, buf, len2)); + EXPECT_TRUE(ReadFromFile(fd, buf, len2, &bytes_read)); + EXPECT_EQ(len2, bytes_read); EXPECT_EQ(0, internal_memcmp(buf, str2, len2)); CloseFile(fd); + +#if SANITIZER_WINDOWS + // No sanitizer needs to delete a file on Windows yet. If we ever do, we can + // add a portable wrapper and test it from here. + ::DeleteFileA(&tmpfile[0]); +#else internal_unlink(tmpfile); -} #endif +} + +static const size_t kStrlcpyBufSize = 8; +void test_internal_strlcpy(char *dbuf, const char *sbuf) { + uptr retval = 0; + retval = internal_strlcpy(dbuf, sbuf, kStrlcpyBufSize); + EXPECT_EQ(internal_strncmp(dbuf, sbuf, kStrlcpyBufSize - 1), 0); + EXPECT_EQ(internal_strlen(dbuf), + std::min(internal_strlen(sbuf), (uptr)(kStrlcpyBufSize - 1))); + EXPECT_EQ(retval, internal_strlen(sbuf)); + + // Test with shorter maxlen. + uptr maxlen = 2; + if (internal_strlen(sbuf) > maxlen) { + retval = internal_strlcpy(dbuf, sbuf, maxlen); + EXPECT_EQ(internal_strncmp(dbuf, sbuf, maxlen - 1), 0); + EXPECT_EQ(internal_strlen(dbuf), maxlen - 1); + } +} TEST(SanitizerCommon, InternalStrFunctions) { const char *haystack = "haystack"; @@ -125,10 +172,45 @@ TEST(SanitizerCommon, InternalStrFunctions) { EXPECT_EQ(haystack + 2, internal_strchrnul(haystack, 'y')); EXPECT_EQ(0, internal_strchr(haystack, 'z')); EXPECT_EQ(haystack + 8, internal_strchrnul(haystack, 'z')); + + char dbuf[kStrlcpyBufSize] = {}; + const char *samesizestr = "1234567"; + const char *shortstr = "123"; + const char *longerstr = "123456789"; + + // Test internal_strlcpy. + internal_strlcpy(dbuf, shortstr, 0); + EXPECT_EQ(dbuf[0], 0); + EXPECT_EQ(dbuf[0], 0); + test_internal_strlcpy(dbuf, samesizestr); + test_internal_strlcpy(dbuf, shortstr); + test_internal_strlcpy(dbuf, longerstr); + + // Test internal_strlcat. + char dcatbuf[kStrlcpyBufSize] = {}; + uptr retval = 0; + retval = internal_strlcat(dcatbuf, "aaa", 0); + EXPECT_EQ(internal_strlen(dcatbuf), (uptr)0); + EXPECT_EQ(retval, (uptr)3); + + retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize); + EXPECT_EQ(internal_strcmp(dcatbuf, "123"), 0); + EXPECT_EQ(internal_strlen(dcatbuf), (uptr)3); + EXPECT_EQ(retval, (uptr)3); + + retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize); + EXPECT_EQ(internal_strcmp(dcatbuf, "123123"), 0); + EXPECT_EQ(internal_strlen(dcatbuf), (uptr)6); + EXPECT_EQ(retval, (uptr)6); + + retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize); + EXPECT_EQ(internal_strcmp(dcatbuf, "1231231"), 0); + EXPECT_EQ(internal_strlen(dcatbuf), (uptr)7); + EXPECT_EQ(retval, (uptr)9); } // FIXME: File manipulations are not yet supported on Windows -#if !defined(_WIN32) && !SANITIZER_MAC +#if SANITIZER_POSIX && !SANITIZER_MAC TEST(SanitizerCommon, InternalMmapWithOffset) { char tmpfile[128]; temp_file_name(tmpfile, sizeof(tmpfile), |