sanitizer_libc_test.cc revision 9578a3ecfc35a264ede1135033398e2a77a6cad6
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 "gtest/gtest.h"
15
16#if defined(__linux__) || defined(__APPLE__)
17# define SANITIZER_TEST_HAS_STAT_H 1
18# include <sys/stat.h>
19#else
20# define SANITIZER_TEST_HAS_STAT_H 0
21#endif
22
23// A regression test for internal_memmove() implementation.
24TEST(SanitizerCommon, InternalMemmoveRegression) {
25  char src[] = "Hello World";
26  char *dest = src + 6;
27  __sanitizer::internal_memmove(dest, src, 5);
28  EXPECT_EQ(dest[0], src[0]);
29  EXPECT_EQ(dest[4], src[4]);
30}
31
32TEST(SanitizerCommon, mem_is_zero) {
33  size_t size = 128;
34  char *x = new char[size];
35  memset(x, 0, size);
36  for (size_t pos = 0; pos < size; pos++) {
37    x[pos] = 1;
38    for (size_t beg = 0; beg < size; beg++) {
39      for (size_t end = beg; end < size; end++) {
40        // fprintf(stderr, "pos %zd beg %zd end %zd \n", pos, beg, end);
41        if (beg <= pos && pos < end)
42          EXPECT_FALSE(__sanitizer::mem_is_zero(x + beg, end - beg));
43        else
44          EXPECT_TRUE(__sanitizer::mem_is_zero(x + beg, end - beg));
45      }
46    }
47    x[pos] = 0;
48  }
49  delete [] x;
50}
51
52struct stat_and_more {
53  struct stat st;
54  unsigned char z;
55};
56
57TEST(SanitizerCommon, FileOps) {
58  const char *str1 = "qwerty";
59  uptr len1 = internal_strlen(str1);
60  const char *str2 = "zxcv";
61  uptr len2 = internal_strlen(str2);
62
63  u32 uid = GetUid();
64  char temp_filename[128];
65#ifdef __ANDROID__
66  // I don't know a way to query temp directory location on Android without
67  // going through Java interfaces. The code below is not ideal, but should
68  // work. May require "adb root", but it is needed for almost any use of ASan
69  // on Android already.
70  internal_snprintf(temp_filename, sizeof(temp_filename),
71                    "%s/sanitizer_common.tmp.%d",
72                    GetEnv("EXTERNAL_STORAGE"), uid);
73#else
74  internal_snprintf(temp_filename, sizeof(temp_filename),
75                    "/tmp/sanitizer_common.tmp.%d", uid);
76#endif
77  uptr openrv = OpenFile(temp_filename, true);
78  EXPECT_EQ(false, internal_iserror(openrv));
79  fd_t fd = openrv;
80  EXPECT_EQ(len1, internal_write(fd, str1, len1));
81  EXPECT_EQ(len2, internal_write(fd, str2, len2));
82  internal_close(fd);
83
84  openrv = OpenFile(temp_filename, false);
85  EXPECT_EQ(false, internal_iserror(openrv));
86  fd = openrv;
87  uptr fsize = internal_filesize(fd);
88  EXPECT_EQ(len1 + len2, fsize);
89
90#if SANITIZER_TEST_HAS_STAT_H
91  struct stat st1, st2, st3;
92  EXPECT_EQ(0u, internal_stat(temp_filename, &st1));
93  EXPECT_EQ(0u, internal_lstat(temp_filename, &st2));
94  EXPECT_EQ(0u, internal_fstat(fd, &st3));
95  EXPECT_EQ(fsize, (uptr)st3.st_size);
96
97  // Verify that internal_fstat does not write beyond the end of the supplied
98  // buffer.
99  struct stat_and_more sam;
100  memset(&sam, 0xAB, sizeof(sam));
101  EXPECT_EQ(0u, internal_fstat(fd, &sam.st));
102  EXPECT_EQ(0xAB, sam.z);
103  EXPECT_NE(0xAB, sam.st.st_size);
104  EXPECT_NE(0, sam.st.st_size);
105#endif
106
107  char buf[64] = {};
108  EXPECT_EQ(len1, internal_read(fd, buf, len1));
109  EXPECT_EQ(0, internal_memcmp(buf, str1, len1));
110  EXPECT_EQ((char)0, buf[len1 + 1]);
111  internal_memset(buf, 0, len1);
112  EXPECT_EQ(len2, internal_read(fd, buf, len2));
113  EXPECT_EQ(0, internal_memcmp(buf, str2, len2));
114  internal_close(fd);
115}
116
117