1 //=-- asan_str_test.cpp ---------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is a part of AddressSanitizer, an address sanity checker.
11 //===----------------------------------------------------------------------===//
12 #include "asan_test_utils.h"
14 #if defined(__APPLE__)
15 #include <AvailabilityMacros.h> // For MAC_OS_X_VERSION_*
18 // Used for string functions tests
19 static char global_string
[] = "global";
20 static size_t global_string_length
= 6;
22 const char kStackReadUnderflow
[] =
23 #if !GTEST_USES_SIMPLE_RE
27 "underflows this variable";
28 const char kStackReadOverflow
[] =
29 #if !GTEST_USES_SIMPLE_RE
33 "overflows this variable";
42 std::string
LeftOOBReadMessage(OOBKind oob_kind
, int oob_distance
) {
43 return oob_kind
== OOBKind::Stack
? kStackReadUnderflow
44 : ::LeftOOBReadMessage(oob_distance
);
47 std::string
RightOOBReadMessage(OOBKind oob_kind
, int oob_distance
) {
48 return oob_kind
== OOBKind::Stack
? kStackReadOverflow
49 : ::RightOOBReadMessage(oob_distance
);
53 // Input to a test is a zero-terminated string str with given length
54 // Accesses to the bytes before and after str
55 // are presumed to produce OOB errors
56 void StrLenOOBTestTemplate(char *str
, size_t length
, OOBKind oob_kind
) {
57 // Normal strlen calls
58 EXPECT_EQ(strlen(str
), length
);
60 EXPECT_EQ(length
- 1, strlen(str
+ 1));
61 EXPECT_EQ(0U, strlen(str
+ length
));
63 // Arg of strlen is not malloced, OOB access
64 if (oob_kind
!= OOBKind::Global
) {
65 // We don't insert RedZones before global variables
66 EXPECT_DEATH(Ident(strlen(str
- 1)), LeftOOBReadMessage(oob_kind
, 1));
67 EXPECT_DEATH(Ident(strlen(str
- 5)), LeftOOBReadMessage(oob_kind
, 5));
69 EXPECT_DEATH(Ident(strlen(str
+ length
+ 1)),
70 RightOOBReadMessage(oob_kind
, 0));
71 // Overwrite terminator
73 // String is not zero-terminated, strlen will lead to OOB access
74 EXPECT_DEATH(Ident(strlen(str
)), RightOOBReadMessage(oob_kind
, 0));
75 EXPECT_DEATH(Ident(strlen(str
+ length
)), RightOOBReadMessage(oob_kind
, 0));
79 TEST(AddressSanitizer
, StrLenOOBTest
) {
80 // Check heap-allocated string
81 size_t length
= Ident(10);
82 char *heap_string
= Ident((char*)malloc(length
+ 1));
83 char stack_string
[10 + 1];
84 break_optimization(&stack_string
);
85 for (size_t i
= 0; i
< length
; i
++) {
87 stack_string
[i
] = 'b';
89 heap_string
[length
] = 0;
90 stack_string
[length
] = 0;
91 StrLenOOBTestTemplate(heap_string
, length
, OOBKind::Heap
);
92 StrLenOOBTestTemplate(stack_string
, length
, OOBKind::Stack
);
93 StrLenOOBTestTemplate(global_string
, global_string_length
, OOBKind::Global
);
97 // 32-bit android libc++-based NDK toolchain links wcslen statically, disabling
99 #if !defined(__ANDROID__) || defined(__LP64__)
100 TEST(AddressSanitizer
, WcsLenTest
) {
101 EXPECT_EQ(0U, wcslen(Ident(L
"")));
102 size_t hello_len
= 13;
103 size_t hello_size
= (hello_len
+ 1) * sizeof(wchar_t);
104 EXPECT_EQ(hello_len
, wcslen(Ident(L
"Hello, World!")));
105 wchar_t *heap_string
= Ident((wchar_t*)malloc(hello_size
));
106 memcpy(heap_string
, L
"Hello, World!", hello_size
);
107 EXPECT_EQ(hello_len
, Ident(wcslen(heap_string
)));
108 EXPECT_DEATH(Ident(wcslen(heap_string
+ 14)), RightOOBReadMessage(0));
113 // This test fails on MinGW-w64 because it still ships a static copy of strnlen
114 // despite it being available from UCRT.
115 #if defined(__MINGW32__)
116 # define MAYBE_StrNLenOOBTest DISABLED_StrNLenOOBTest
118 # define MAYBE_StrNLenOOBTest StrNLenOOBTest
121 #if SANITIZER_TEST_HAS_STRNLEN
122 TEST(AddressSanitizer
, MAYBE_StrNLenOOBTest
) {
123 size_t size
= Ident(123);
124 char *str
= MallocAndMemsetString(size
);
125 // Normal strnlen calls.
126 Ident(strnlen(str
- 1, 0));
127 Ident(strnlen(str
, size
));
128 Ident(strnlen(str
+ size
- 1, 1));
129 str
[size
- 1] = '\0';
130 Ident(strnlen(str
, 2 * size
));
131 // Argument points to not allocated memory.
132 EXPECT_DEATH(Ident(strnlen(str
- 1, 1)), LeftOOBReadMessage(1));
133 EXPECT_DEATH(Ident(strnlen(str
+ size
, 1)), RightOOBReadMessage(0));
134 // Overwrite the terminating '\0' and hit unallocated memory.
136 EXPECT_DEATH(Ident(strnlen(str
, size
+ 1)), RightOOBReadMessage(0));
139 #endif // SANITIZER_TEST_HAS_STRNLEN
141 // This test fails with the WinASan dynamic runtime because we fail to intercept
143 #if (defined(_MSC_VER) && defined(_DLL)) || defined(__MINGW32__)
144 # define MAYBE_StrDupOOBTest DISABLED_StrDupOOBTest
146 # define MAYBE_StrDupOOBTest StrDupOOBTest
149 TEST(AddressSanitizer
, MAYBE_StrDupOOBTest
) {
150 size_t size
= Ident(42);
151 char *str
= MallocAndMemsetString(size
);
153 // Normal strdup calls.
154 str
[size
- 1] = '\0';
155 new_str
= strdup(str
);
157 new_str
= strdup(str
+ size
- 1);
159 // Argument points to not allocated memory.
160 EXPECT_DEATH(Ident(strdup(str
- 1)), LeftOOBReadMessage(1));
161 EXPECT_DEATH(Ident(strdup(str
+ size
)), RightOOBReadMessage(0));
162 // Overwrite the terminating '\0' and hit unallocated memory.
164 EXPECT_DEATH(Ident(strdup(str
)), RightOOBReadMessage(0));
168 #if SANITIZER_TEST_HAS_STRNDUP
169 TEST(AddressSanitizer
, MAYBE_StrNDupOOBTest
) {
170 size_t size
= Ident(42);
171 char *str
= MallocAndMemsetString(size
);
173 // Normal strndup calls.
174 str
[size
- 1] = '\0';
175 new_str
= strndup(str
, size
- 13);
177 new_str
= strndup(str
+ size
- 1, 13);
179 // Argument points to not allocated memory.
180 EXPECT_DEATH(Ident(strndup(str
- 1, 13)), LeftOOBReadMessage(1));
181 EXPECT_DEATH(Ident(strndup(str
+ size
, 13)), RightOOBReadMessage(0));
182 // Overwrite the terminating '\0' and hit unallocated memory.
184 EXPECT_DEATH(Ident(strndup(str
, size
+ 13)), RightOOBReadMessage(0));
185 // Check handling of non 0 terminated strings.
186 Ident(new_str
= strndup(str
+ size
- 1, 0));
188 Ident(new_str
= strndup(str
+ size
- 1, 1));
190 EXPECT_DEATH(Ident(strndup(str
+ size
- 1, 2)), RightOOBReadMessage(0));
193 #endif // SANITIZER_TEST_HAS_STRNDUP
195 TEST(AddressSanitizer
, StrCpyOOBTest
) {
196 size_t to_size
= Ident(30);
197 size_t from_size
= Ident(6); // less than to_size
198 char *to
= Ident((char*)malloc(to_size
));
199 char *from
= Ident((char*)malloc(from_size
));
200 // Normal strcpy calls.
201 strcpy(from
, "hello");
203 strcpy(to
+ to_size
- from_size
, from
);
204 // Length of "from" is too small.
205 EXPECT_DEATH(Ident(strcpy(from
, "hello2")), RightOOBWriteMessage(0));
206 // "to" or "from" points to not allocated memory.
207 EXPECT_DEATH(Ident(strcpy(to
- 1, from
)), LeftOOBWriteMessage(1));
208 EXPECT_DEATH(Ident(strcpy(to
, from
- 1)), LeftOOBReadMessage(1));
209 EXPECT_DEATH(Ident(strcpy(to
, from
+ from_size
)), RightOOBReadMessage(0));
210 EXPECT_DEATH(Ident(strcpy(to
+ to_size
, from
)), RightOOBWriteMessage(0));
211 // Overwrite the terminating '\0' character and hit unallocated memory.
212 from
[from_size
- 1] = '!';
213 EXPECT_DEATH(Ident(strcpy(to
, from
)), RightOOBReadMessage(0));
218 TEST(AddressSanitizer
, StrNCpyOOBTest
) {
219 size_t to_size
= Ident(20);
220 size_t from_size
= Ident(6); // less than to_size
221 char *to
= Ident((char*)malloc(to_size
));
222 // From is a zero-terminated string "hello\0" of length 6
223 char *from
= Ident((char*)malloc(from_size
));
224 strcpy(from
, "hello");
226 strncpy(to
, from
, 0);
227 strncpy(to
- 1, from
- 1, 0);
228 // normal strncpy calls
229 strncpy(to
, from
, from_size
);
230 strncpy(to
, from
, to_size
);
231 strncpy(to
, from
+ from_size
- 1, to_size
);
232 strncpy(to
+ to_size
- 1, from
, 1);
233 // One of {to, from} points to not allocated memory
234 EXPECT_DEATH(Ident(strncpy(to
, from
- 1, from_size
)),
235 LeftOOBReadMessage(1));
236 EXPECT_DEATH(Ident(strncpy(to
- 1, from
, from_size
)),
237 LeftOOBWriteMessage(1));
238 EXPECT_DEATH(Ident(strncpy(to
, from
+ from_size
, 1)),
239 RightOOBReadMessage(0));
240 EXPECT_DEATH(Ident(strncpy(to
+ to_size
, from
, 1)),
241 RightOOBWriteMessage(0));
242 // Length of "to" is too small
243 EXPECT_DEATH(Ident(strncpy(to
+ to_size
- from_size
+ 1, from
, from_size
)),
244 RightOOBWriteMessage(0));
245 EXPECT_DEATH(Ident(strncpy(to
+ 1, from
, to_size
)),
246 RightOOBWriteMessage(0));
247 // Overwrite terminator in from
248 from
[from_size
- 1] = '!';
249 // normal strncpy call
250 strncpy(to
, from
, from_size
);
251 // Length of "from" is too small
252 EXPECT_DEATH(Ident(strncpy(to
, from
, to_size
)),
253 RightOOBReadMessage(0));
258 // Users may have different definitions of "strchr" and "index", so provide
259 // function pointer typedefs and overload RunStrChrTest implementation.
260 // We can't use macro for RunStrChrTest body here, as this macro would
261 // confuse EXPECT_DEATH gtest macro.
262 typedef char*(*PointerToStrChr1
)(const char*, int);
263 typedef char*(*PointerToStrChr2
)(char*, int);
265 template<typename StrChrFn
>
266 static void RunStrChrTestImpl(StrChrFn
*StrChr
) {
267 size_t size
= Ident(100);
268 char *str
= MallocAndMemsetString(size
);
271 EXPECT_EQ(str
, StrChr(str
, 'z'));
272 EXPECT_EQ(str
+ 10, StrChr(str
, 'q'));
273 EXPECT_EQ(NULL
, StrChr(str
, 'a'));
274 // StrChr argument points to not allocated memory.
275 EXPECT_DEATH(Ident(StrChr(str
- 1, 'z')), LeftOOBReadMessage(1));
276 EXPECT_DEATH(Ident(StrChr(str
+ size
, 'z')), RightOOBReadMessage(0));
277 // Overwrite the terminator and hit not allocated memory.
279 EXPECT_DEATH(Ident(StrChr(str
, 'a')), RightOOBReadMessage(0));
283 // Prefer to use the standard signature if both are available.
284 UNUSED
static void RunStrChrTest(PointerToStrChr1 StrChr
, ...) {
285 RunStrChrTestImpl(StrChr
);
287 UNUSED
static void RunStrChrTest(PointerToStrChr2 StrChr
, int) {
288 RunStrChrTestImpl(StrChr
);
291 TEST(AddressSanitizer
, StrChrAndIndexOOBTest
) {
292 RunStrChrTest(&strchr
, 0);
293 // No index() on Windows and on Android L.
294 #if !defined(_WIN32) && !defined(__ANDROID__)
295 RunStrChrTest(&index
, 0);
299 TEST(AddressSanitizer
, StrCmpAndFriendsLogicTest
) {
301 EXPECT_EQ(0, strcmp("", ""));
302 EXPECT_EQ(0, strcmp("abcd", "abcd"));
303 EXPECT_GT(0, strcmp("ab", "ac"));
304 EXPECT_GT(0, strcmp("abc", "abcd"));
305 EXPECT_LT(0, strcmp("acc", "abc"));
306 EXPECT_LT(0, strcmp("abcd", "abc"));
309 EXPECT_EQ(0, strncmp("a", "b", 0));
310 EXPECT_EQ(0, strncmp("abcd", "abcd", 10));
311 EXPECT_EQ(0, strncmp("abcd", "abcef", 3));
312 EXPECT_GT(0, strncmp("abcde", "abcfa", 4));
313 EXPECT_GT(0, strncmp("a", "b", 5));
314 EXPECT_GT(0, strncmp("bc", "bcde", 4));
315 EXPECT_LT(0, strncmp("xyz", "xyy", 10));
316 EXPECT_LT(0, strncmp("baa", "aaa", 1));
317 EXPECT_LT(0, strncmp("zyx", "", 2));
319 #if !defined(_WIN32) // no str[n]casecmp on Windows.
321 EXPECT_EQ(0, strcasecmp("", ""));
322 EXPECT_EQ(0, strcasecmp("zzz", "zzz"));
323 EXPECT_EQ(0, strcasecmp("abCD", "ABcd"));
324 EXPECT_GT(0, strcasecmp("aB", "Ac"));
325 EXPECT_GT(0, strcasecmp("ABC", "ABCd"));
326 EXPECT_LT(0, strcasecmp("acc", "abc"));
327 EXPECT_LT(0, strcasecmp("ABCd", "abc"));
330 EXPECT_EQ(0, strncasecmp("a", "b", 0));
331 EXPECT_EQ(0, strncasecmp("abCD", "ABcd", 10));
332 EXPECT_EQ(0, strncasecmp("abCd", "ABcef", 3));
333 EXPECT_GT(0, strncasecmp("abcde", "ABCfa", 4));
334 EXPECT_GT(0, strncasecmp("a", "B", 5));
335 EXPECT_GT(0, strncasecmp("bc", "BCde", 4));
336 EXPECT_LT(0, strncasecmp("xyz", "xyy", 10));
337 EXPECT_LT(0, strncasecmp("Baa", "aaa", 1));
338 EXPECT_LT(0, strncasecmp("zyx", "", 2));
342 EXPECT_EQ(0, memcmp("a", "b", 0));
343 EXPECT_EQ(0, memcmp("ab\0c", "ab\0c", 4));
344 EXPECT_GT(0, memcmp("\0ab", "\0ac", 3));
345 EXPECT_GT(0, memcmp("abb\0", "abba", 4));
346 EXPECT_LT(0, memcmp("ab\0cd", "ab\0c\0", 5));
347 EXPECT_LT(0, memcmp("zza", "zyx", 3));
350 typedef int(*PointerToStrCmp
)(const char*, const char*);
351 void RunStrCmpTest(PointerToStrCmp StrCmp
) {
352 size_t size
= Ident(100);
354 char *s1
= MallocAndMemsetString(size
, fill
);
355 char *s2
= MallocAndMemsetString(size
, fill
);
358 // Normal StrCmp calls
359 Ident(StrCmp(s1
, s2
));
360 Ident(StrCmp(s1
, s2
+ size
- 1));
361 Ident(StrCmp(s1
+ size
- 1, s2
+ size
- 1));
362 // One of arguments points to not allocated memory.
363 EXPECT_DEATH(Ident(StrCmp
)(s1
- 1, s2
), LeftOOBReadMessage(1));
364 EXPECT_DEATH(Ident(StrCmp
)(s1
, s2
- 1), LeftOOBReadMessage(1));
365 EXPECT_DEATH(Ident(StrCmp
)(s1
+ size
, s2
), RightOOBReadMessage(0));
366 EXPECT_DEATH(Ident(StrCmp
)(s1
, s2
+ size
), RightOOBReadMessage(0));
367 // Hit unallocated memory and die.
369 EXPECT_DEATH(Ident(StrCmp
)(s1
, s1
), RightOOBReadMessage(0));
370 EXPECT_DEATH(Ident(StrCmp
)(s1
+ size
- 1, s2
), RightOOBReadMessage(0));
375 TEST(AddressSanitizer
, StrCmpOOBTest
) {
376 RunStrCmpTest(&strcmp
);
379 #if !defined(_WIN32) // no str[n]casecmp on Windows.
380 TEST(AddressSanitizer
, StrCaseCmpOOBTest
) {
381 RunStrCmpTest(&strcasecmp
);
385 typedef int(*PointerToStrNCmp
)(const char*, const char*, size_t);
386 void RunStrNCmpTest(PointerToStrNCmp StrNCmp
) {
387 size_t size
= Ident(100);
388 char *s1
= MallocAndMemsetString(size
);
389 char *s2
= MallocAndMemsetString(size
);
392 // Normal StrNCmp calls
393 Ident(StrNCmp(s1
, s2
, size
+ 2));
396 Ident(StrNCmp(s1
+ size
- 2, s2
+ size
- 2, size
));
398 Ident(StrNCmp(s1
- 1, s2
- 1, 0));
399 Ident(StrNCmp(s1
+ size
- 1, s2
+ size
- 1, 1));
400 // One of arguments points to not allocated memory.
401 EXPECT_DEATH(Ident(StrNCmp
)(s1
- 1, s2
, 1), LeftOOBReadMessage(1));
402 EXPECT_DEATH(Ident(StrNCmp
)(s1
, s2
- 1, 1), LeftOOBReadMessage(1));
403 EXPECT_DEATH(Ident(StrNCmp
)(s1
+ size
, s2
, 1), RightOOBReadMessage(0));
404 EXPECT_DEATH(Ident(StrNCmp
)(s1
, s2
+ size
, 1), RightOOBReadMessage(0));
405 // Hit unallocated memory and die.
406 EXPECT_DEATH(Ident(StrNCmp
)(s1
+ 1, s2
+ 1, size
), RightOOBReadMessage(0));
407 EXPECT_DEATH(Ident(StrNCmp
)(s1
+ size
- 1, s2
, 2), RightOOBReadMessage(0));
412 TEST(AddressSanitizer
, StrNCmpOOBTest
) {
413 RunStrNCmpTest(&strncmp
);
416 #if !defined(_WIN32) // no str[n]casecmp on Windows.
417 TEST(AddressSanitizer
, StrNCaseCmpOOBTest
) {
418 RunStrNCmpTest(&strncasecmp
);
422 TEST(AddressSanitizer
, StrCatOOBTest
) {
423 // strcat() reads strlen(to) bytes from |to| before concatenating.
424 size_t to_size
= Ident(100);
425 char *to
= MallocAndMemsetString(to_size
);
427 size_t from_size
= Ident(20);
428 char *from
= MallocAndMemsetString(from_size
);
429 from
[from_size
- 1] = '\0';
430 // Normal strcat calls.
433 strcat(to
+ from_size
, from
+ from_size
- 2);
434 // Passing an invalid pointer is an error even when concatenating an empty
436 EXPECT_DEATH(strcat(to
- 1, from
+ from_size
- 1), LeftOOBAccessMessage(1));
437 // One of arguments points to not allocated memory.
438 EXPECT_DEATH(strcat(to
- 1, from
), LeftOOBAccessMessage(1));
439 EXPECT_DEATH(strcat(to
, from
- 1), LeftOOBReadMessage(1));
440 EXPECT_DEATH(strcat(to
, from
+ from_size
), RightOOBReadMessage(0));
442 // "from" is not zero-terminated.
443 from
[from_size
- 1] = 'z';
444 EXPECT_DEATH(strcat(to
, from
), RightOOBReadMessage(0));
445 from
[from_size
- 1] = '\0';
446 // "to" is too short to fit "from".
447 memset(to
, 'z', to_size
);
448 to
[to_size
- from_size
+ 1] = '\0';
449 EXPECT_DEATH(strcat(to
, from
), RightOOBWriteMessage(0));
450 // length of "to" is just enough.
451 strcat(to
, from
+ 1);
457 TEST(AddressSanitizer
, StrNCatOOBTest
) {
458 // strncat() reads strlen(to) bytes from |to| before concatenating.
459 size_t to_size
= Ident(100);
460 char *to
= MallocAndMemsetString(to_size
);
462 size_t from_size
= Ident(20);
463 char *from
= MallocAndMemsetString(from_size
);
464 // Normal strncat calls.
465 strncat(to
, from
, 0);
466 strncat(to
, from
, from_size
);
467 from
[from_size
- 1] = '\0';
468 strncat(to
, from
, 2 * from_size
);
469 strncat(to
, from
+ from_size
- 1, 10);
470 // One of arguments points to not allocated memory.
471 EXPECT_DEATH(strncat(to
- 1, from
, 2), LeftOOBAccessMessage(1));
472 EXPECT_DEATH(strncat(to
, from
- 1, 2), LeftOOBReadMessage(1));
473 EXPECT_DEATH(strncat(to
, from
+ from_size
, 2), RightOOBReadMessage(0));
475 memset(from
, 'z', from_size
);
476 memset(to
, 'z', to_size
);
478 // "from" is too short.
479 EXPECT_DEATH(strncat(to
, from
, from_size
+ 1), RightOOBReadMessage(0));
480 // "to" is too short to fit "from".
482 to
[to_size
- from_size
+ 1] = '\0';
483 EXPECT_DEATH(strncat(to
, from
, from_size
- 1), RightOOBWriteMessage(0));
484 // "to" is just enough.
485 strncat(to
, from
, from_size
- 2);
491 static std::string
OverlapErrorMessage(const std::string
&func
) {
492 return func
+ "-param-overlap";
495 TEST(AddressSanitizer
, StrArgsOverlapTest
) {
496 size_t size
= Ident(100);
497 char *str
= Ident((char*)malloc(size
));
499 // Do not check memcpy() on OS X 10.7 and later, where it actually aliases
501 #if !defined(__APPLE__) || !defined(MAC_OS_X_VERSION_10_7) || \
502 (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
503 // Check "memcpy". Use Ident() to avoid inlining.
504 #if PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE
505 memset(str
, 'z', size
);
506 Ident(memcpy
)(str
+ 1, str
+ 11, 10);
507 Ident(memcpy
)(str
, str
, 0);
508 EXPECT_DEATH(Ident(memcpy
)(str
, str
+ 14, 15), OverlapErrorMessage("memcpy"));
509 EXPECT_DEATH(Ident(memcpy
)(str
+ 14, str
, 15), OverlapErrorMessage("memcpy"));
513 // We do not treat memcpy with to==from as a bug.
514 // See http://llvm.org/bugs/show_bug.cgi?id=11763.
515 // EXPECT_DEATH(Ident(memcpy)(str + 20, str + 20, 1),
516 // OverlapErrorMessage("memcpy"));
519 memset(str
, 'z', size
);
521 strcpy(str
+ 10, str
);
522 EXPECT_DEATH(strcpy(str
+ 9, str
), OverlapErrorMessage("strcpy"));
523 EXPECT_DEATH(strcpy(str
, str
+ 4), OverlapErrorMessage("strcpy"));
524 strcpy(str
, str
+ 5);
527 memset(str
, 'z', size
);
528 strncpy(str
, str
+ 10, 10);
529 EXPECT_DEATH(strncpy(str
, str
+ 9, 10), OverlapErrorMessage("strncpy"));
530 EXPECT_DEATH(strncpy(str
+ 9, str
, 10), OverlapErrorMessage("strncpy"));
532 strncpy(str
+ 11, str
, 20);
533 EXPECT_DEATH(strncpy(str
+ 10, str
, 20), OverlapErrorMessage("strncpy"));
536 memset(str
, 'z', size
);
539 strcat(str
, str
+ 10);
540 EXPECT_DEATH(strcat(str
, str
+ 11), OverlapErrorMessage("strcat"));
542 strcat(str
+ 11, str
);
543 EXPECT_DEATH(strcat(str
, str
+ 9), OverlapErrorMessage("strcat"));
544 EXPECT_DEATH(strcat(str
+ 9, str
), OverlapErrorMessage("strcat"));
545 EXPECT_DEATH(strcat(str
+ 10, str
), OverlapErrorMessage("strcat"));
548 memset(str
, 'z', size
);
550 strncat(str
, str
+ 10, 10); // from is empty
551 EXPECT_DEATH(strncat(str
, str
+ 11, 10), OverlapErrorMessage("strncat"));
554 strncat(str
+ 5, str
, 5);
556 EXPECT_DEATH(strncat(str
+ 5, str
, 6), OverlapErrorMessage("strncat"));
557 EXPECT_DEATH(strncat(str
, str
+ 9, 10), OverlapErrorMessage("strncat"));
562 typedef void(*PointerToCallAtoi
)(const char*);
564 void RunAtoiOOBTest(PointerToCallAtoi Atoi
) {
565 char *array
= MallocAndMemsetString(10, '1');
566 // Invalid pointer to the string.
567 EXPECT_DEATH(Atoi(array
+ 11), RightOOBReadMessage(1));
568 EXPECT_DEATH(Atoi(array
- 1), LeftOOBReadMessage(1));
569 // Die if a buffer doesn't have terminating NULL.
570 EXPECT_DEATH(Atoi(array
), RightOOBReadMessage(0));
571 // Make last symbol a terminating NULL
574 // Sometimes we need to detect overflow if no digits are found.
575 memset(array
, ' ', 10);
576 EXPECT_DEATH(Atoi(array
), RightOOBReadMessage(0));
578 EXPECT_DEATH(Atoi(array
), RightOOBReadMessage(0));
579 EXPECT_DEATH(Atoi(array
+ 9), RightOOBReadMessage(0));
583 #if !defined(_WIN32) // FIXME: Fix and enable on Windows.
584 void CallAtoi(const char *nptr
) {
587 void CallAtol(const char *nptr
) {
590 void CallAtoll(const char *nptr
) {
593 TEST(AddressSanitizer
, AtoiAndFriendsOOBTest
) {
594 RunAtoiOOBTest(&CallAtoi
);
595 RunAtoiOOBTest(&CallAtol
);
596 RunAtoiOOBTest(&CallAtoll
);
600 typedef void(*PointerToCallStrtol
)(const char*, char**, int);
602 void RunStrtolOOBTest(PointerToCallStrtol Strtol
) {
603 char *array
= MallocAndMemsetString(3);
607 // Invalid pointer to the string.
608 EXPECT_DEATH(Strtol(array
+ 3, NULL
, 0), RightOOBReadMessage(0));
609 EXPECT_DEATH(Strtol(array
- 1, NULL
, 0), LeftOOBReadMessage(1));
610 // Buffer overflow if there is no terminating null (depends on base).
611 EXPECT_DEATH(Strtol(array
, NULL
, 0), RightOOBReadMessage(0));
613 EXPECT_DEATH(Strtol(array
, NULL
, 36), RightOOBReadMessage(0));
614 // Add terminating zero to get rid of overflow.
616 Strtol(array
, NULL
, 36);
617 // Sometimes we need to detect overflow if no digits are found.
618 array
[0] = array
[1] = array
[2] = ' ';
619 EXPECT_DEATH(Strtol(array
, NULL
, 0), RightOOBReadMessage(0));
621 EXPECT_DEATH(Strtol(array
, NULL
, 0), RightOOBReadMessage(0));
623 EXPECT_DEATH(Strtol(array
, NULL
, 0), RightOOBReadMessage(0));
627 #if !defined(_WIN32) // FIXME: Fix and enable on Windows.
628 void CallStrtol(const char *nptr
, char **endptr
, int base
) {
629 Ident(strtol(nptr
, endptr
, base
));
631 void CallStrtoll(const char *nptr
, char **endptr
, int base
) {
632 Ident(strtoll(nptr
, endptr
, base
));
634 TEST(AddressSanitizer
, StrtollOOBTest
) {
635 RunStrtolOOBTest(&CallStrtoll
);
637 TEST(AddressSanitizer
, StrtolOOBTest
) {
638 RunStrtolOOBTest(&CallStrtol
);