asan_str_test.cc revision 2d1fdb26e458c4ddc04155c1d421bced3ba90cd0
1//=-- asan_str_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//
10// This file is a part of AddressSanitizer, an address sanity checker.
11//
12//===----------------------------------------------------------------------===//
13#include "asan_test_utils.h"
14
15#if defined(__APPLE__)
16#include <AvailabilityMacros.h>  // For MAC_OS_X_VERSION_*
17#endif
18
19// Used for string functions tests
20static char global_string[] = "global";
21static size_t global_string_length = 6;
22
23// Input to a test is a zero-terminated string str with given length
24// Accesses to the bytes to the left and to the right of str
25// are presumed to produce OOB errors
26void StrLenOOBTestTemplate(char *str, size_t length, bool is_global) {
27  // Normal strlen calls
28  EXPECT_EQ(strlen(str), length);
29  if (length > 0) {
30    EXPECT_EQ(length - 1, strlen(str + 1));
31    EXPECT_EQ(0U, strlen(str + length));
32  }
33  // Arg of strlen is not malloced, OOB access
34  if (!is_global) {
35    // We don't insert RedZones to the left of global variables
36    EXPECT_DEATH(Ident(strlen(str - 1)), LeftOOBReadMessage(1));
37    EXPECT_DEATH(Ident(strlen(str - 5)), LeftOOBReadMessage(5));
38  }
39  EXPECT_DEATH(Ident(strlen(str + length + 1)), RightOOBReadMessage(0));
40  // Overwrite terminator
41  str[length] = 'a';
42  // String is not zero-terminated, strlen will lead to OOB access
43  EXPECT_DEATH(Ident(strlen(str)), RightOOBReadMessage(0));
44  EXPECT_DEATH(Ident(strlen(str + length)), RightOOBReadMessage(0));
45  // Restore terminator
46  str[length] = 0;
47}
48TEST(AddressSanitizer, StrLenOOBTest) {
49  // Check heap-allocated string
50  size_t length = Ident(10);
51  char *heap_string = Ident((char*)malloc(length + 1));
52  char stack_string[10 + 1];
53  break_optimization(&stack_string);
54  for (size_t i = 0; i < length; i++) {
55    heap_string[i] = 'a';
56    stack_string[i] = 'b';
57  }
58  heap_string[length] = 0;
59  stack_string[length] = 0;
60  StrLenOOBTestTemplate(heap_string, length, false);
61  // TODO(samsonov): Fix expected messages in StrLenOOBTestTemplate to
62  //      make test for stack_string work. Or move it to output tests.
63  // StrLenOOBTestTemplate(stack_string, length, false);
64  StrLenOOBTestTemplate(global_string, global_string_length, true);
65  free(heap_string);
66}
67
68TEST(AddressSanitizer, WcsLenTest) {
69  EXPECT_EQ(0U, wcslen(Ident(L"")));
70  size_t hello_len = 13;
71  size_t hello_size = (hello_len + 1) * sizeof(wchar_t);
72  EXPECT_EQ(hello_len, wcslen(Ident(L"Hello, World!")));
73  wchar_t *heap_string = Ident((wchar_t*)malloc(hello_size));
74  memcpy(heap_string, L"Hello, World!", hello_size);
75  EXPECT_EQ(hello_len, Ident(wcslen(heap_string)));
76  EXPECT_DEATH(Ident(wcslen(heap_string + 14)), RightOOBReadMessage(0));
77  free(heap_string);
78}
79
80#if SANITIZER_TEST_HAS_STRNLEN
81TEST(AddressSanitizer, StrNLenOOBTest) {
82  size_t size = Ident(123);
83  char *str = MallocAndMemsetString(size);
84  // Normal strnlen calls.
85  Ident(strnlen(str - 1, 0));
86  Ident(strnlen(str, size));
87  Ident(strnlen(str + size - 1, 1));
88  str[size - 1] = '\0';
89  Ident(strnlen(str, 2 * size));
90  // Argument points to not allocated memory.
91  EXPECT_DEATH(Ident(strnlen(str - 1, 1)), LeftOOBReadMessage(1));
92  EXPECT_DEATH(Ident(strnlen(str + size, 1)), RightOOBReadMessage(0));
93  // Overwrite the terminating '\0' and hit unallocated memory.
94  str[size - 1] = 'z';
95  EXPECT_DEATH(Ident(strnlen(str, size + 1)), RightOOBReadMessage(0));
96  free(str);
97}
98#endif  // SANITIZER_TEST_HAS_STRNLEN
99
100TEST(AddressSanitizer, StrDupOOBTest) {
101  size_t size = Ident(42);
102  char *str = MallocAndMemsetString(size);
103  char *new_str;
104  // Normal strdup calls.
105  str[size - 1] = '\0';
106  new_str = strdup(str);
107  free(new_str);
108  new_str = strdup(str + size - 1);
109  free(new_str);
110  // Argument points to not allocated memory.
111  EXPECT_DEATH(Ident(strdup(str - 1)), LeftOOBReadMessage(1));
112  EXPECT_DEATH(Ident(strdup(str + size)), RightOOBReadMessage(0));
113  // Overwrite the terminating '\0' and hit unallocated memory.
114  str[size - 1] = 'z';
115  EXPECT_DEATH(Ident(strdup(str)), RightOOBReadMessage(0));
116  free(str);
117}
118
119TEST(AddressSanitizer, StrCpyOOBTest) {
120  size_t to_size = Ident(30);
121  size_t from_size = Ident(6);  // less than to_size
122  char *to = Ident((char*)malloc(to_size));
123  char *from = Ident((char*)malloc(from_size));
124  // Normal strcpy calls.
125  strcpy(from, "hello");
126  strcpy(to, from);
127  strcpy(to + to_size - from_size, from);
128  // Length of "from" is too small.
129  EXPECT_DEATH(Ident(strcpy(from, "hello2")), RightOOBWriteMessage(0));
130  // "to" or "from" points to not allocated memory.
131  EXPECT_DEATH(Ident(strcpy(to - 1, from)), LeftOOBWriteMessage(1));
132  EXPECT_DEATH(Ident(strcpy(to, from - 1)), LeftOOBReadMessage(1));
133  EXPECT_DEATH(Ident(strcpy(to, from + from_size)), RightOOBReadMessage(0));
134  EXPECT_DEATH(Ident(strcpy(to + to_size, from)), RightOOBWriteMessage(0));
135  // Overwrite the terminating '\0' character and hit unallocated memory.
136  from[from_size - 1] = '!';
137  EXPECT_DEATH(Ident(strcpy(to, from)), RightOOBReadMessage(0));
138  free(to);
139  free(from);
140}
141
142TEST(AddressSanitizer, StrNCpyOOBTest) {
143  size_t to_size = Ident(20);
144  size_t from_size = Ident(6);  // less than to_size
145  char *to = Ident((char*)malloc(to_size));
146  // From is a zero-terminated string "hello\0" of length 6
147  char *from = Ident((char*)malloc(from_size));
148  strcpy(from, "hello");
149  // copy 0 bytes
150  strncpy(to, from, 0);
151  strncpy(to - 1, from - 1, 0);
152  // normal strncpy calls
153  strncpy(to, from, from_size);
154  strncpy(to, from, to_size);
155  strncpy(to, from + from_size - 1, to_size);
156  strncpy(to + to_size - 1, from, 1);
157  // One of {to, from} points to not allocated memory
158  EXPECT_DEATH(Ident(strncpy(to, from - 1, from_size)),
159               LeftOOBReadMessage(1));
160  EXPECT_DEATH(Ident(strncpy(to - 1, from, from_size)),
161               LeftOOBWriteMessage(1));
162  EXPECT_DEATH(Ident(strncpy(to, from + from_size, 1)),
163               RightOOBReadMessage(0));
164  EXPECT_DEATH(Ident(strncpy(to + to_size, from, 1)),
165               RightOOBWriteMessage(0));
166  // Length of "to" is too small
167  EXPECT_DEATH(Ident(strncpy(to + to_size - from_size + 1, from, from_size)),
168               RightOOBWriteMessage(0));
169  EXPECT_DEATH(Ident(strncpy(to + 1, from, to_size)),
170               RightOOBWriteMessage(0));
171  // Overwrite terminator in from
172  from[from_size - 1] = '!';
173  // normal strncpy call
174  strncpy(to, from, from_size);
175  // Length of "from" is too small
176  EXPECT_DEATH(Ident(strncpy(to, from, to_size)),
177               RightOOBReadMessage(0));
178  free(to);
179  free(from);
180}
181
182// Users may have different definitions of "strchr" and "index", so provide
183// function pointer typedefs and overload RunStrChrTest implementation.
184// We can't use macro for RunStrChrTest body here, as this macro would
185// confuse EXPECT_DEATH gtest macro.
186typedef char*(*PointerToStrChr1)(const char*, int);
187typedef char*(*PointerToStrChr2)(char*, int);
188
189UNUSED static void RunStrChrTest(PointerToStrChr1 StrChr) {
190  size_t size = Ident(100);
191  char *str = MallocAndMemsetString(size);
192  str[10] = 'q';
193  str[11] = '\0';
194  EXPECT_EQ(str, StrChr(str, 'z'));
195  EXPECT_EQ(str + 10, StrChr(str, 'q'));
196  EXPECT_EQ(NULL, StrChr(str, 'a'));
197  // StrChr argument points to not allocated memory.
198  EXPECT_DEATH(Ident(StrChr(str - 1, 'z')), LeftOOBReadMessage(1));
199  EXPECT_DEATH(Ident(StrChr(str + size, 'z')), RightOOBReadMessage(0));
200  // Overwrite the terminator and hit not allocated memory.
201  str[11] = 'z';
202  EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0));
203  free(str);
204}
205UNUSED static void RunStrChrTest(PointerToStrChr2 StrChr) {
206  size_t size = Ident(100);
207  char *str = MallocAndMemsetString(size);
208  str[10] = 'q';
209  str[11] = '\0';
210  EXPECT_EQ(str, StrChr(str, 'z'));
211  EXPECT_EQ(str + 10, StrChr(str, 'q'));
212  EXPECT_EQ(NULL, StrChr(str, 'a'));
213  // StrChr argument points to not allocated memory.
214  EXPECT_DEATH(Ident(StrChr(str - 1, 'z')), LeftOOBReadMessage(1));
215  EXPECT_DEATH(Ident(StrChr(str + size, 'z')), RightOOBReadMessage(0));
216  // Overwrite the terminator and hit not allocated memory.
217  str[11] = 'z';
218  EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0));
219  free(str);
220}
221
222TEST(AddressSanitizer, StrChrAndIndexOOBTest) {
223  RunStrChrTest(&strchr);
224#if !defined(_WIN32)  // no index() on Windows.
225  RunStrChrTest(&index);
226#endif
227}
228
229TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) {
230  // strcmp
231  EXPECT_EQ(0, strcmp("", ""));
232  EXPECT_EQ(0, strcmp("abcd", "abcd"));
233  EXPECT_GT(0, strcmp("ab", "ac"));
234  EXPECT_GT(0, strcmp("abc", "abcd"));
235  EXPECT_LT(0, strcmp("acc", "abc"));
236  EXPECT_LT(0, strcmp("abcd", "abc"));
237
238  // strncmp
239  EXPECT_EQ(0, strncmp("a", "b", 0));
240  EXPECT_EQ(0, strncmp("abcd", "abcd", 10));
241  EXPECT_EQ(0, strncmp("abcd", "abcef", 3));
242  EXPECT_GT(0, strncmp("abcde", "abcfa", 4));
243  EXPECT_GT(0, strncmp("a", "b", 5));
244  EXPECT_GT(0, strncmp("bc", "bcde", 4));
245  EXPECT_LT(0, strncmp("xyz", "xyy", 10));
246  EXPECT_LT(0, strncmp("baa", "aaa", 1));
247  EXPECT_LT(0, strncmp("zyx", "", 2));
248
249#if !defined(_WIN32)  // no str[n]casecmp on Windows.
250  // strcasecmp
251  EXPECT_EQ(0, strcasecmp("", ""));
252  EXPECT_EQ(0, strcasecmp("zzz", "zzz"));
253  EXPECT_EQ(0, strcasecmp("abCD", "ABcd"));
254  EXPECT_GT(0, strcasecmp("aB", "Ac"));
255  EXPECT_GT(0, strcasecmp("ABC", "ABCd"));
256  EXPECT_LT(0, strcasecmp("acc", "abc"));
257  EXPECT_LT(0, strcasecmp("ABCd", "abc"));
258
259  // strncasecmp
260  EXPECT_EQ(0, strncasecmp("a", "b", 0));
261  EXPECT_EQ(0, strncasecmp("abCD", "ABcd", 10));
262  EXPECT_EQ(0, strncasecmp("abCd", "ABcef", 3));
263  EXPECT_GT(0, strncasecmp("abcde", "ABCfa", 4));
264  EXPECT_GT(0, strncasecmp("a", "B", 5));
265  EXPECT_GT(0, strncasecmp("bc", "BCde", 4));
266  EXPECT_LT(0, strncasecmp("xyz", "xyy", 10));
267  EXPECT_LT(0, strncasecmp("Baa", "aaa", 1));
268  EXPECT_LT(0, strncasecmp("zyx", "", 2));
269#endif
270
271  // memcmp
272  EXPECT_EQ(0, memcmp("a", "b", 0));
273  EXPECT_EQ(0, memcmp("ab\0c", "ab\0c", 4));
274  EXPECT_GT(0, memcmp("\0ab", "\0ac", 3));
275  EXPECT_GT(0, memcmp("abb\0", "abba", 4));
276  EXPECT_LT(0, memcmp("ab\0cd", "ab\0c\0", 5));
277  EXPECT_LT(0, memcmp("zza", "zyx", 3));
278}
279
280typedef int(*PointerToStrCmp)(const char*, const char*);
281void RunStrCmpTest(PointerToStrCmp StrCmp) {
282  size_t size = Ident(100);
283  int fill = 'o';
284  char *s1 = MallocAndMemsetString(size, fill);
285  char *s2 = MallocAndMemsetString(size, fill);
286  s1[size - 1] = '\0';
287  s2[size - 1] = '\0';
288  // Normal StrCmp calls
289  Ident(StrCmp(s1, s2));
290  Ident(StrCmp(s1, s2 + size - 1));
291  Ident(StrCmp(s1 + size - 1, s2 + size - 1));
292  s1[size - 1] = 'z';
293  s2[size - 1] = 'x';
294  Ident(StrCmp(s1, s2));
295  // One of arguments points to not allocated memory.
296  EXPECT_DEATH(Ident(StrCmp)(s1 - 1, s2), LeftOOBReadMessage(1));
297  EXPECT_DEATH(Ident(StrCmp)(s1, s2 - 1), LeftOOBReadMessage(1));
298  EXPECT_DEATH(Ident(StrCmp)(s1 + size, s2), RightOOBReadMessage(0));
299  EXPECT_DEATH(Ident(StrCmp)(s1, s2 + size), RightOOBReadMessage(0));
300  // Hit unallocated memory and die.
301  s1[size - 1] = fill;
302  EXPECT_DEATH(Ident(StrCmp)(s1, s1), RightOOBReadMessage(0));
303  EXPECT_DEATH(Ident(StrCmp)(s1 + size - 1, s2), RightOOBReadMessage(0));
304  free(s1);
305  free(s2);
306}
307
308TEST(AddressSanitizer, StrCmpOOBTest) {
309  RunStrCmpTest(&strcmp);
310}
311
312#if !defined(_WIN32)  // no str[n]casecmp on Windows.
313TEST(AddressSanitizer, StrCaseCmpOOBTest) {
314  RunStrCmpTest(&strcasecmp);
315}
316#endif
317
318typedef int(*PointerToStrNCmp)(const char*, const char*, size_t);
319void RunStrNCmpTest(PointerToStrNCmp StrNCmp) {
320  size_t size = Ident(100);
321  char *s1 = MallocAndMemsetString(size);
322  char *s2 = MallocAndMemsetString(size);
323  s1[size - 1] = '\0';
324  s2[size - 1] = '\0';
325  // Normal StrNCmp calls
326  Ident(StrNCmp(s1, s2, size + 2));
327  s1[size - 1] = 'z';
328  s2[size - 1] = 'x';
329  Ident(StrNCmp(s1 + size - 2, s2 + size - 2, size));
330  s2[size - 1] = 'z';
331  Ident(StrNCmp(s1 - 1, s2 - 1, 0));
332  Ident(StrNCmp(s1 + size - 1, s2 + size - 1, 1));
333  // One of arguments points to not allocated memory.
334  EXPECT_DEATH(Ident(StrNCmp)(s1 - 1, s2, 1), LeftOOBReadMessage(1));
335  EXPECT_DEATH(Ident(StrNCmp)(s1, s2 - 1, 1), LeftOOBReadMessage(1));
336  EXPECT_DEATH(Ident(StrNCmp)(s1 + size, s2, 1), RightOOBReadMessage(0));
337  EXPECT_DEATH(Ident(StrNCmp)(s1, s2 + size, 1), RightOOBReadMessage(0));
338  // Hit unallocated memory and die.
339  EXPECT_DEATH(Ident(StrNCmp)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0));
340  EXPECT_DEATH(Ident(StrNCmp)(s1 + size - 1, s2, 2), RightOOBReadMessage(0));
341  free(s1);
342  free(s2);
343}
344
345TEST(AddressSanitizer, StrNCmpOOBTest) {
346  RunStrNCmpTest(&strncmp);
347}
348
349#if !defined(_WIN32)  // no str[n]casecmp on Windows.
350TEST(AddressSanitizer, StrNCaseCmpOOBTest) {
351  RunStrNCmpTest(&strncasecmp);
352}
353#endif
354
355TEST(AddressSanitizer, StrCatOOBTest) {
356  // strcat() reads strlen(to) bytes from |to| before concatenating.
357  size_t to_size = Ident(100);
358  char *to = MallocAndMemsetString(to_size);
359  to[0] = '\0';
360  size_t from_size = Ident(20);
361  char *from = MallocAndMemsetString(from_size);
362  from[from_size - 1] = '\0';
363  // Normal strcat calls.
364  strcat(to, from);
365  strcat(to, from);
366  strcat(to + from_size, from + from_size - 2);
367  // Passing an invalid pointer is an error even when concatenating an empty
368  // string.
369  EXPECT_DEATH(strcat(to - 1, from + from_size - 1), LeftOOBAccessMessage(1));
370  // One of arguments points to not allocated memory.
371  EXPECT_DEATH(strcat(to - 1, from), LeftOOBAccessMessage(1));
372  EXPECT_DEATH(strcat(to, from - 1), LeftOOBReadMessage(1));
373  EXPECT_DEATH(strcat(to + to_size, from), RightOOBWriteMessage(0));
374  EXPECT_DEATH(strcat(to, from + from_size), RightOOBReadMessage(0));
375
376  // "from" is not zero-terminated.
377  from[from_size - 1] = 'z';
378  EXPECT_DEATH(strcat(to, from), RightOOBReadMessage(0));
379  from[from_size - 1] = '\0';
380  // "to" is not zero-terminated.
381  memset(to, 'z', to_size);
382  EXPECT_DEATH(strcat(to, from), RightOOBWriteMessage(0));
383  // "to" is too short to fit "from".
384  to[to_size - from_size + 1] = '\0';
385  EXPECT_DEATH(strcat(to, from), RightOOBWriteMessage(0));
386  // length of "to" is just enough.
387  strcat(to, from + 1);
388
389  free(to);
390  free(from);
391}
392
393TEST(AddressSanitizer, StrNCatOOBTest) {
394  // strncat() reads strlen(to) bytes from |to| before concatenating.
395  size_t to_size = Ident(100);
396  char *to = MallocAndMemsetString(to_size);
397  to[0] = '\0';
398  size_t from_size = Ident(20);
399  char *from = MallocAndMemsetString(from_size);
400  // Normal strncat calls.
401  strncat(to, from, 0);
402  strncat(to, from, from_size);
403  from[from_size - 1] = '\0';
404  strncat(to, from, 2 * from_size);
405  // Catenating empty string with an invalid string is still an error.
406  EXPECT_DEATH(strncat(to - 1, from, 0), LeftOOBAccessMessage(1));
407  strncat(to, from + from_size - 1, 10);
408  // One of arguments points to not allocated memory.
409  EXPECT_DEATH(strncat(to - 1, from, 2), LeftOOBAccessMessage(1));
410  EXPECT_DEATH(strncat(to, from - 1, 2), LeftOOBReadMessage(1));
411  EXPECT_DEATH(strncat(to + to_size, from, 2), RightOOBWriteMessage(0));
412  EXPECT_DEATH(strncat(to, from + from_size, 2), RightOOBReadMessage(0));
413
414  memset(from, 'z', from_size);
415  memset(to, 'z', to_size);
416  to[0] = '\0';
417  // "from" is too short.
418  EXPECT_DEATH(strncat(to, from, from_size + 1), RightOOBReadMessage(0));
419  // "to" is not zero-terminated.
420  EXPECT_DEATH(strncat(to + 1, from, 1), RightOOBWriteMessage(0));
421  // "to" is too short to fit "from".
422  to[0] = 'z';
423  to[to_size - from_size + 1] = '\0';
424  EXPECT_DEATH(strncat(to, from, from_size - 1), RightOOBWriteMessage(0));
425  // "to" is just enough.
426  strncat(to, from, from_size - 2);
427
428  free(to);
429  free(from);
430}
431
432static string OverlapErrorMessage(const string &func) {
433  return func + "-param-overlap";
434}
435
436TEST(AddressSanitizer, StrArgsOverlapTest) {
437  size_t size = Ident(100);
438  char *str = Ident((char*)malloc(size));
439
440// Do not check memcpy() on OS X 10.7 and later, where it actually aliases
441// memmove().
442#if !defined(__APPLE__) || !defined(MAC_OS_X_VERSION_10_7) || \
443    (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
444  // Check "memcpy". Use Ident() to avoid inlining.
445  memset(str, 'z', size);
446  Ident(memcpy)(str + 1, str + 11, 10);
447  Ident(memcpy)(str, str, 0);
448  EXPECT_DEATH(Ident(memcpy)(str, str + 14, 15), OverlapErrorMessage("memcpy"));
449  EXPECT_DEATH(Ident(memcpy)(str + 14, str, 15), OverlapErrorMessage("memcpy"));
450#endif
451
452  // We do not treat memcpy with to==from as a bug.
453  // See http://llvm.org/bugs/show_bug.cgi?id=11763.
454  // EXPECT_DEATH(Ident(memcpy)(str + 20, str + 20, 1),
455  //              OverlapErrorMessage("memcpy"));
456
457  // Check "strcpy".
458  memset(str, 'z', size);
459  str[9] = '\0';
460  strcpy(str + 10, str);
461  EXPECT_DEATH(strcpy(str + 9, str), OverlapErrorMessage("strcpy"));
462  EXPECT_DEATH(strcpy(str, str + 4), OverlapErrorMessage("strcpy"));
463  strcpy(str, str + 5);
464
465  // Check "strncpy".
466  memset(str, 'z', size);
467  strncpy(str, str + 10, 10);
468  EXPECT_DEATH(strncpy(str, str + 9, 10), OverlapErrorMessage("strncpy"));
469  EXPECT_DEATH(strncpy(str + 9, str, 10), OverlapErrorMessage("strncpy"));
470  str[10] = '\0';
471  strncpy(str + 11, str, 20);
472  EXPECT_DEATH(strncpy(str + 10, str, 20), OverlapErrorMessage("strncpy"));
473
474  // Check "strcat".
475  memset(str, 'z', size);
476  str[10] = '\0';
477  str[20] = '\0';
478  strcat(str, str + 10);
479  EXPECT_DEATH(strcat(str, str + 11), OverlapErrorMessage("strcat"));
480  str[10] = '\0';
481  strcat(str + 11, str);
482  EXPECT_DEATH(strcat(str, str + 9), OverlapErrorMessage("strcat"));
483  EXPECT_DEATH(strcat(str + 9, str), OverlapErrorMessage("strcat"));
484  EXPECT_DEATH(strcat(str + 10, str), OverlapErrorMessage("strcat"));
485
486  // Check "strncat".
487  memset(str, 'z', size);
488  str[10] = '\0';
489  strncat(str, str + 10, 10);  // from is empty
490  EXPECT_DEATH(strncat(str, str + 11, 10), OverlapErrorMessage("strncat"));
491  str[10] = '\0';
492  str[20] = '\0';
493  strncat(str + 5, str, 5);
494  str[10] = '\0';
495  EXPECT_DEATH(strncat(str + 5, str, 6), OverlapErrorMessage("strncat"));
496  EXPECT_DEATH(strncat(str, str + 9, 10), OverlapErrorMessage("strncat"));
497
498  free(str);
499}
500
501void CallAtoi(const char *nptr) {
502  Ident(atoi(nptr));
503}
504void CallAtol(const char *nptr) {
505  Ident(atol(nptr));
506}
507void CallAtoll(const char *nptr) {
508  Ident(atoll(nptr));
509}
510typedef void(*PointerToCallAtoi)(const char*);
511
512void RunAtoiOOBTest(PointerToCallAtoi Atoi) {
513  char *array = MallocAndMemsetString(10, '1');
514  // Invalid pointer to the string.
515  EXPECT_DEATH(Atoi(array + 11), RightOOBReadMessage(1));
516  EXPECT_DEATH(Atoi(array - 1), LeftOOBReadMessage(1));
517  // Die if a buffer doesn't have terminating NULL.
518  EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));
519  // Make last symbol a terminating NULL or other non-digit.
520  array[9] = '\0';
521  Atoi(array);
522  array[9] = 'a';
523  Atoi(array);
524  Atoi(array + 9);
525  // Sometimes we need to detect overflow if no digits are found.
526  memset(array, ' ', 10);
527  EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));
528  array[9] = '-';
529  EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));
530  EXPECT_DEATH(Atoi(array + 9), RightOOBReadMessage(0));
531  array[8] = '-';
532  Atoi(array);
533  free(array);
534}
535
536#if !defined(_WIN32)  // FIXME: Fix and enable on Windows.
537TEST(AddressSanitizer, AtoiAndFriendsOOBTest) {
538  RunAtoiOOBTest(&CallAtoi);
539  RunAtoiOOBTest(&CallAtol);
540  RunAtoiOOBTest(&CallAtoll);
541}
542#endif
543
544void CallStrtol(const char *nptr, char **endptr, int base) {
545  Ident(strtol(nptr, endptr, base));
546}
547void CallStrtoll(const char *nptr, char **endptr, int base) {
548  Ident(strtoll(nptr, endptr, base));
549}
550typedef void(*PointerToCallStrtol)(const char*, char**, int);
551
552void RunStrtolOOBTest(PointerToCallStrtol Strtol) {
553  char *array = MallocAndMemsetString(3);
554  char *endptr = NULL;
555  array[0] = '1';
556  array[1] = '2';
557  array[2] = '3';
558  // Invalid pointer to the string.
559  EXPECT_DEATH(Strtol(array + 3, NULL, 0), RightOOBReadMessage(0));
560  EXPECT_DEATH(Strtol(array - 1, NULL, 0), LeftOOBReadMessage(1));
561  // Buffer overflow if there is no terminating null (depends on base).
562  Strtol(array, &endptr, 3);
563  EXPECT_EQ(array + 2, endptr);
564  EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
565  array[2] = 'z';
566  Strtol(array, &endptr, 35);
567  EXPECT_EQ(array + 2, endptr);
568  EXPECT_DEATH(Strtol(array, NULL, 36), RightOOBReadMessage(0));
569  // Add terminating zero to get rid of overflow.
570  array[2] = '\0';
571  Strtol(array, NULL, 36);
572  // Don't check for overflow if base is invalid.
573  Strtol(array - 1, NULL, -1);
574  Strtol(array + 3, NULL, 1);
575  // Sometimes we need to detect overflow if no digits are found.
576  array[0] = array[1] = array[2] = ' ';
577  EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
578  array[2] = '+';
579  EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
580  array[2] = '-';
581  EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
582  array[1] = '+';
583  Strtol(array, NULL, 0);
584  array[1] = array[2] = 'z';
585  Strtol(array, &endptr, 0);
586  EXPECT_EQ(array, endptr);
587  Strtol(array + 2, NULL, 0);
588  EXPECT_EQ(array, endptr);
589  free(array);
590}
591
592#if !defined(_WIN32)  // FIXME: Fix and enable on Windows.
593TEST(AddressSanitizer, StrtollOOBTest) {
594  RunStrtolOOBTest(&CallStrtoll);
595}
596TEST(AddressSanitizer, StrtolOOBTest) {
597  RunStrtolOOBTest(&CallStrtol);
598}
599#endif
600
601
602