sanitizer_libc_test.cc revision a615b26e3e3c2da0b2f950f506f6c2c220430c19
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
58TEST(SanitizerCommon, FileOps) {
59  const char *str1 = "qwerty";
60  uptr len1 = internal_strlen(str1);
61  const char *str2 = "zxcv";
62  uptr len2 = internal_strlen(str2);
63
64  u32 uid = GetUid();
65  char temp_filename[128];
66#if SANITIZER_ANDROID
67  // I don't know a way to query temp directory location on Android without
68  // going through Java interfaces. The code below is not ideal, but should
69  // work. May require "adb root", but it is needed for almost any use of ASan
70  // on Android already.
71  internal_snprintf(temp_filename, sizeof(temp_filename),
72                    "%s/sanitizer_common.tmp.%d",
73                    GetEnv("EXTERNAL_STORAGE"), uid);
74#else
75  internal_snprintf(temp_filename, sizeof(temp_filename),
76                    "/tmp/sanitizer_common.tmp.%d", uid);
77#endif
78  uptr openrv = OpenFile(temp_filename, true);
79  EXPECT_FALSE(internal_iserror(openrv));
80  fd_t fd = openrv;
81  EXPECT_EQ(len1, internal_write(fd, str1, len1));
82  EXPECT_EQ(len2, internal_write(fd, str2, len2));
83  internal_close(fd);
84
85  openrv = OpenFile(temp_filename, false);
86  EXPECT_FALSE(internal_iserror(openrv));
87  fd = openrv;
88  uptr fsize = internal_filesize(fd);
89  EXPECT_EQ(len1 + len2, fsize);
90
91#if SANITIZER_TEST_HAS_STAT_H
92  struct stat st1, st2, st3;
93  EXPECT_EQ(0u, internal_stat(temp_filename, &st1));
94  EXPECT_EQ(0u, internal_lstat(temp_filename, &st2));
95  EXPECT_EQ(0u, internal_fstat(fd, &st3));
96  EXPECT_EQ(fsize, (uptr)st3.st_size);
97
98  // Verify that internal_fstat does not write beyond the end of the supplied
99  // buffer.
100  struct stat_and_more sam;
101  memset(&sam, 0xAB, sizeof(sam));
102  EXPECT_EQ(0u, internal_fstat(fd, &sam.st));
103  EXPECT_EQ(0xAB, sam.z);
104  EXPECT_NE(0xAB, sam.st.st_size);
105  EXPECT_NE(0, sam.st.st_size);
106#endif
107
108  char buf[64] = {};
109  EXPECT_EQ(len1, internal_read(fd, buf, len1));
110  EXPECT_EQ(0, internal_memcmp(buf, str1, len1));
111  EXPECT_EQ((char)0, buf[len1 + 1]);
112  internal_memset(buf, 0, len1);
113  EXPECT_EQ(len2, internal_read(fd, buf, len2));
114  EXPECT_EQ(0, internal_memcmp(buf, str2, len2));
115  internal_close(fd);
116}
117
118