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