aboutsummaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/tests/sanitizer_libc_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sanitizer_common/tests/sanitizer_libc_test.cc')
-rw-r--r--lib/sanitizer_common/tests/sanitizer_libc_test.cc108
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),