]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc
Update compiler-rt to 3.7.0 release. This also includes the sanitizer
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / sanitizer_common / tests / sanitizer_libc_test.cc
1 //===-- sanitizer_libc_test.cc --------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // Tests for sanitizer_libc.h.
10 //===----------------------------------------------------------------------===//
11
12 #include "sanitizer_common/sanitizer_common.h"
13 #include "sanitizer_common/sanitizer_libc.h"
14 #include "sanitizer_common/sanitizer_platform.h"
15 #include "gtest/gtest.h"
16
17 #if SANITIZER_LINUX || SANITIZER_MAC
18 # define SANITIZER_TEST_HAS_STAT_H 1
19 # include <sys/stat.h>
20 # include "sanitizer_common/sanitizer_posix.h"
21 #else
22 # define SANITIZER_TEST_HAS_STAT_H 0
23 #endif
24
25 // A regression test for internal_memmove() implementation.
26 TEST(SanitizerCommon, InternalMemmoveRegression) {
27   char src[] = "Hello World";
28   char *dest = src + 6;
29   __sanitizer::internal_memmove(dest, src, 5);
30   EXPECT_EQ(dest[0], src[0]);
31   EXPECT_EQ(dest[4], src[4]);
32 }
33
34 TEST(SanitizerCommon, mem_is_zero) {
35   size_t size = 128;
36   char *x = new char[size];
37   memset(x, 0, size);
38   for (size_t pos = 0; pos < size; pos++) {
39     x[pos] = 1;
40     for (size_t beg = 0; beg < size; beg++) {
41       for (size_t end = beg; end < size; end++) {
42         // fprintf(stderr, "pos %zd beg %zd end %zd \n", pos, beg, end);
43         if (beg <= pos && pos < end)
44           EXPECT_FALSE(__sanitizer::mem_is_zero(x + beg, end - beg));
45         else
46           EXPECT_TRUE(__sanitizer::mem_is_zero(x + beg, end - beg));
47       }
48     }
49     x[pos] = 0;
50   }
51   delete [] x;
52 }
53
54 struct stat_and_more {
55   struct stat st;
56   unsigned char z;
57 };
58
59 static void temp_file_name(char *buf, size_t bufsize, const char *prefix) {
60   const char *tmpdir = "/tmp";
61 #if SANITIZER_ANDROID
62   // I don't know a way to query temp directory location on Android without
63   // going through Java interfaces. The code below is not ideal, but should
64   // work. May require "adb root", but it is needed for almost any use of ASan
65   // on Android already.
66   tmpdir = GetEnv("EXTERNAL_STORAGE");
67 #endif
68   u32 uid = GetUid();
69   internal_snprintf(buf, bufsize, "%s/%s%d", tmpdir, prefix, uid);
70 }
71
72 // FIXME: File manipulations are not yet supported on Windows
73 #if !defined(_WIN32)
74 TEST(SanitizerCommon, FileOps) {
75   const char *str1 = "qwerty";
76   uptr len1 = internal_strlen(str1);
77   const char *str2 = "zxcv";
78   uptr len2 = internal_strlen(str2);
79
80   char tmpfile[128];
81   temp_file_name(tmpfile, sizeof(tmpfile), "sanitizer_common.fileops.tmp.");
82   fd_t fd = OpenFile(tmpfile, WrOnly);
83   ASSERT_NE(fd, kInvalidFd);
84   EXPECT_EQ(len1, internal_write(fd, str1, len1));
85   EXPECT_EQ(len2, internal_write(fd, str2, len2));
86   CloseFile(fd);
87
88   fd = OpenFile(tmpfile, RdOnly);
89   ASSERT_NE(fd, kInvalidFd);
90   uptr fsize = internal_filesize(fd);
91   EXPECT_EQ(len1 + len2, fsize);
92
93 #if SANITIZER_TEST_HAS_STAT_H
94   struct stat st1, st2, st3;
95   EXPECT_EQ(0u, internal_stat(tmpfile, &st1));
96   EXPECT_EQ(0u, internal_lstat(tmpfile, &st2));
97   EXPECT_EQ(0u, internal_fstat(fd, &st3));
98   EXPECT_EQ(fsize, (uptr)st3.st_size);
99
100   // Verify that internal_fstat does not write beyond the end of the supplied
101   // buffer.
102   struct stat_and_more sam;
103   memset(&sam, 0xAB, sizeof(sam));
104   EXPECT_EQ(0u, internal_fstat(fd, &sam.st));
105   EXPECT_EQ(0xAB, sam.z);
106   EXPECT_NE(0xAB, sam.st.st_size);
107   EXPECT_NE(0, sam.st.st_size);
108 #endif
109
110   char buf[64] = {};
111   EXPECT_EQ(len1, internal_read(fd, buf, len1));
112   EXPECT_EQ(0, internal_memcmp(buf, str1, len1));
113   EXPECT_EQ((char)0, buf[len1 + 1]);
114   internal_memset(buf, 0, len1);
115   EXPECT_EQ(len2, internal_read(fd, buf, len2));
116   EXPECT_EQ(0, internal_memcmp(buf, str2, len2));
117   CloseFile(fd);
118   internal_unlink(tmpfile);
119 }
120 #endif
121
122 TEST(SanitizerCommon, InternalStrFunctions) {
123   const char *haystack = "haystack";
124   EXPECT_EQ(haystack + 2, internal_strchr(haystack, 'y'));
125   EXPECT_EQ(haystack + 2, internal_strchrnul(haystack, 'y'));
126   EXPECT_EQ(0, internal_strchr(haystack, 'z'));
127   EXPECT_EQ(haystack + 8, internal_strchrnul(haystack, 'z'));
128 }
129
130 // FIXME: File manipulations are not yet supported on Windows
131 #if !defined(_WIN32) && !SANITIZER_MAC
132 TEST(SanitizerCommon, InternalMmapWithOffset) {
133   char tmpfile[128];
134   temp_file_name(tmpfile, sizeof(tmpfile),
135                  "sanitizer_common.internalmmapwithoffset.tmp.");
136   fd_t fd = OpenFile(tmpfile, RdWr);
137   ASSERT_NE(fd, kInvalidFd);
138
139   uptr page_size = GetPageSizeCached();
140   uptr res = internal_ftruncate(fd, page_size * 2);
141   ASSERT_FALSE(internal_iserror(res));
142
143   res = internal_lseek(fd, page_size, SEEK_SET);
144   ASSERT_FALSE(internal_iserror(res));
145
146   res = internal_write(fd, "AB", 2);
147   ASSERT_FALSE(internal_iserror(res));
148
149   char *p = (char *)MapWritableFileToMemory(nullptr, page_size, fd, page_size);
150   ASSERT_NE(nullptr, p);
151
152   ASSERT_EQ('A', p[0]);
153   ASSERT_EQ('B', p[1]);
154
155   CloseFile(fd);
156   UnmapOrDie(p, page_size);
157   internal_unlink(tmpfile);
158 }
159 #endif