sanitizer_libc_test.cc revision 2d1fdb26e458c4ddc04155c1d421bced3ba90cd0
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#else
21# define SANITIZER_TEST_HAS_STAT_H 0
22#endif
23
24// A regression test for internal_memmove() implementation.
25TEST(SanitizerCommon, InternalMemmoveRegression) {
26  char src[] = "Hello World";
27  char *dest = src + 6;
28  __sanitizer::internal_memmove(dest, src, 5);
29  EXPECT_EQ(dest[0], src[0]);
30  EXPECT_EQ(dest[4], src[4]);
31}
32
33TEST(SanitizerCommon, mem_is_zero) {
34  size_t size = 128;
35  char *x = new char[size];
36  memset(x, 0, size);
37  for (size_t pos = 0; pos < size; pos++) {
38    x[pos] = 1;
39    for (size_t beg = 0; beg < size; beg++) {
40      for (size_t end = beg; end < size; end++) {
41        // fprintf(stderr, "pos %zd beg %zd end %zd \n", pos, beg, end);
42        if (beg <= pos && pos < end)
43          EXPECT_FALSE(__sanitizer::mem_is_zero(x + beg, end - beg));
44        else
45          EXPECT_TRUE(__sanitizer::mem_is_zero(x + beg, end - beg));
46      }
47    }
48    x[pos] = 0;
49  }
50  delete [] x;
51}
52
53struct stat_and_more {
54  struct stat st;
55  unsigned char z;
56};
57
58// FIXME: File manipulations are not yet supported on Windows
59#if !defined(_WIN32)
60TEST(SanitizerCommon, FileOps) {
61  const char *str1 = "qwerty";
62  uptr len1 = internal_strlen(str1);
63  const char *str2 = "zxcv";
64  uptr len2 = internal_strlen(str2);
65
66  u32 uid = GetUid();
67  char temp_filename[128];
68#if SANITIZER_ANDROID
69  // I don't know a way to query temp directory location on Android without
70  // going through Java interfaces. The code below is not ideal, but should
71  // work. May require "adb root", but it is needed for almost any use of ASan
72  // on Android already.
73  internal_snprintf(temp_filename, sizeof(temp_filename),
74                    "%s/sanitizer_common.tmp.%d",
75                    GetEnv("EXTERNAL_STORAGE"), uid);
76#else
77  internal_snprintf(temp_filename, sizeof(temp_filename),
78                    "/tmp/sanitizer_common.tmp.%d", uid);
79#endif
80  uptr openrv = OpenFile(temp_filename, true);
81  EXPECT_FALSE(internal_iserror(openrv));
82  fd_t fd = openrv;
83  EXPECT_EQ(len1, internal_write(fd, str1, len1));
84  EXPECT_EQ(len2, internal_write(fd, str2, len2));
85  internal_close(fd);
86
87  openrv = OpenFile(temp_filename, false);
88  EXPECT_FALSE(internal_iserror(openrv));
89  fd = openrv;
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(temp_filename, &st1));
96  EXPECT_EQ(0u, internal_lstat(temp_filename, &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  internal_close(fd);
118}
119#endif
120
121TEST(SanitizerCommon, InternalStrFunctions) {
122  const char *haystack = "haystack";
123  EXPECT_EQ(haystack + 2, internal_strchr(haystack, 'y'));
124  EXPECT_EQ(haystack + 2, internal_strchrnul(haystack, 'y'));
125  EXPECT_EQ(0, internal_strchr(haystack, 'z'));
126  EXPECT_EQ(haystack + 8, internal_strchrnul(haystack, 'z'));
127}
128