18fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany//=-- asan_str_test.cc ----------------------------------------------------===// 28fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// 38fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// The LLVM Compiler Infrastructure 48fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// 58fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// This file is distributed under the University of Illinois Open Source 68fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// License. See LICENSE.TXT for details. 78fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// 88fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany//===----------------------------------------------------------------------===// 98fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// 108fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker. 118fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// 128fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany//===----------------------------------------------------------------------===// 138fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany#include "asan_test_utils.h" 148fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 15b812253202f2db9d60a543b22226064d1ed20279Alexander Potapenko#if defined(__APPLE__) 16b812253202f2db9d60a543b22226064d1ed20279Alexander Potapenko#include <AvailabilityMacros.h> // For MAC_OS_X_VERSION_* 17b812253202f2db9d60a543b22226064d1ed20279Alexander Potapenko#endif 18d4d7040ee026ab04502c42327ed5081f704a8e3cAlexander Potapenko 198fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// Used for string functions tests 208fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanystatic char global_string[] = "global"; 218fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanystatic size_t global_string_length = 6; 228fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 238fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// Input to a test is a zero-terminated string str with given length 248fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// Accesses to the bytes to the left and to the right of str 258fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// are presumed to produce OOB errors 268fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanyvoid StrLenOOBTestTemplate(char *str, size_t length, bool is_global) { 278fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal strlen calls 288fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(strlen(str), length); 298fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany if (length > 0) { 308fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(length - 1, strlen(str + 1)); 318fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0U, strlen(str + length)); 328fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany } 338fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Arg of strlen is not malloced, OOB access 348fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany if (!is_global) { 358fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // We don't insert RedZones to the left of global variables 368fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strlen(str - 1)), LeftOOBReadMessage(1)); 378fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strlen(str - 5)), LeftOOBReadMessage(5)); 388fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany } 398fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strlen(str + length + 1)), RightOOBReadMessage(0)); 408fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Overwrite terminator 418fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[length] = 'a'; 428fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // String is not zero-terminated, strlen will lead to OOB access 438fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strlen(str)), RightOOBReadMessage(0)); 448fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strlen(str + length)), RightOOBReadMessage(0)); 458fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Restore terminator 468fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[length] = 0; 478fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 488fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrLenOOBTest) { 498fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Check heap-allocated string 508fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t length = Ident(10); 518fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *heap_string = Ident((char*)malloc(length + 1)); 528fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char stack_string[10 + 1]; 538fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany break_optimization(&stack_string); 548fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany for (size_t i = 0; i < length; i++) { 558fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany heap_string[i] = 'a'; 568fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany stack_string[i] = 'b'; 578fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany } 588fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany heap_string[length] = 0; 598fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany stack_string[length] = 0; 608fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany StrLenOOBTestTemplate(heap_string, length, false); 618fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // TODO(samsonov): Fix expected messages in StrLenOOBTestTemplate to 628fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // make test for stack_string work. Or move it to output tests. 638fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // StrLenOOBTestTemplate(stack_string, length, false); 648fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany StrLenOOBTestTemplate(global_string, global_string_length, true); 658fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(heap_string); 668fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 678fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 68b99228de65b408b0acd9618b92774fb8add7e482Reid KlecknerTEST(AddressSanitizer, WcsLenTest) { 69e9e4f04e8320d35ab19dfb8688a7bdd3e5ae7cbbAlexey Samsonov EXPECT_EQ(0U, wcslen(Ident(L""))); 70b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner size_t hello_len = 13; 71b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner size_t hello_size = (hello_len + 1) * sizeof(wchar_t); 72b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner EXPECT_EQ(hello_len, wcslen(Ident(L"Hello, World!"))); 73b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner wchar_t *heap_string = Ident((wchar_t*)malloc(hello_size)); 74b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner memcpy(heap_string, L"Hello, World!", hello_size); 75b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner EXPECT_EQ(hello_len, Ident(wcslen(heap_string))); 76b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner EXPECT_DEATH(Ident(wcslen(heap_string + 14)), RightOOBReadMessage(0)); 771a249181dcdf217d368fbf4c1f09d8af7e617cb0Alexey Samsonov free(heap_string); 78b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner} 79b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner 802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_TEST_HAS_STRNLEN 818fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrNLenOOBTest) { 828fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t size = Ident(123); 838fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *str = MallocAndMemsetString(size); 848fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal strnlen calls. 858fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(strnlen(str - 1, 0)); 868fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(strnlen(str, size)); 878fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(strnlen(str + size - 1, 1)); 888fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[size - 1] = '\0'; 898fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(strnlen(str, 2 * size)); 908fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Argument points to not allocated memory. 918fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strnlen(str - 1, 1)), LeftOOBReadMessage(1)); 928fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strnlen(str + size, 1)), RightOOBReadMessage(0)); 938fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Overwrite the terminating '\0' and hit unallocated memory. 948fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[size - 1] = 'z'; 958fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strnlen(str, size + 1)), RightOOBReadMessage(0)); 968fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(str); 978fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 982d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif // SANITIZER_TEST_HAS_STRNLEN 998fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 1008fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrDupOOBTest) { 1018fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t size = Ident(42); 1028fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *str = MallocAndMemsetString(size); 1038fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *new_str; 1048fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal strdup calls. 1058fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[size - 1] = '\0'; 1068fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany new_str = strdup(str); 1078fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(new_str); 1088fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany new_str = strdup(str + size - 1); 1098fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(new_str); 1108fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Argument points to not allocated memory. 1118fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strdup(str - 1)), LeftOOBReadMessage(1)); 1128fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strdup(str + size)), RightOOBReadMessage(0)); 1138fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Overwrite the terminating '\0' and hit unallocated memory. 1148fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[size - 1] = 'z'; 1158fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strdup(str)), RightOOBReadMessage(0)); 1168fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(str); 1178fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 1188fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 1198fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrCpyOOBTest) { 1208fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t to_size = Ident(30); 1218fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t from_size = Ident(6); // less than to_size 1228fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *to = Ident((char*)malloc(to_size)); 1238fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *from = Ident((char*)malloc(from_size)); 1248fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal strcpy calls. 1258fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcpy(from, "hello"); 1268fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcpy(to, from); 1278fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcpy(to + to_size - from_size, from); 1288fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Length of "from" is too small. 1298fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strcpy(from, "hello2")), RightOOBWriteMessage(0)); 1308fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // "to" or "from" points to not allocated memory. 1318fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strcpy(to - 1, from)), LeftOOBWriteMessage(1)); 1328fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strcpy(to, from - 1)), LeftOOBReadMessage(1)); 1338fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strcpy(to, from + from_size)), RightOOBReadMessage(0)); 1348fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strcpy(to + to_size, from)), RightOOBWriteMessage(0)); 1358fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Overwrite the terminating '\0' character and hit unallocated memory. 1368fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany from[from_size - 1] = '!'; 1378fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strcpy(to, from)), RightOOBReadMessage(0)); 1388fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(to); 1398fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(from); 1408fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 1418fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 1428fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrNCpyOOBTest) { 1438fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t to_size = Ident(20); 1448fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t from_size = Ident(6); // less than to_size 1458fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *to = Ident((char*)malloc(to_size)); 1468fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // From is a zero-terminated string "hello\0" of length 6 1478fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *from = Ident((char*)malloc(from_size)); 1488fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcpy(from, "hello"); 1498fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // copy 0 bytes 1508fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(to, from, 0); 1518fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(to - 1, from - 1, 0); 1528fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // normal strncpy calls 1538fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(to, from, from_size); 1548fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(to, from, to_size); 1558fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(to, from + from_size - 1, to_size); 1568fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(to + to_size - 1, from, 1); 1578fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // One of {to, from} points to not allocated memory 1588fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strncpy(to, from - 1, from_size)), 1598fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany LeftOOBReadMessage(1)); 1608fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strncpy(to - 1, from, from_size)), 1618fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany LeftOOBWriteMessage(1)); 1628fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strncpy(to, from + from_size, 1)), 1638fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RightOOBReadMessage(0)); 1648fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strncpy(to + to_size, from, 1)), 1658fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RightOOBWriteMessage(0)); 1668fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Length of "to" is too small 1678fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strncpy(to + to_size - from_size + 1, from, from_size)), 1688fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RightOOBWriteMessage(0)); 1698fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strncpy(to + 1, from, to_size)), 1708fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RightOOBWriteMessage(0)); 1718fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Overwrite terminator in from 1728fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany from[from_size - 1] = '!'; 1738fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // normal strncpy call 1748fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(to, from, from_size); 1758fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Length of "from" is too small 1768fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strncpy(to, from, to_size)), 1778fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RightOOBReadMessage(0)); 1788fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(to); 1798fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(from); 1808fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 1818fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 1828fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// Users may have different definitions of "strchr" and "index", so provide 1838fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// function pointer typedefs and overload RunStrChrTest implementation. 1848fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// We can't use macro for RunStrChrTest body here, as this macro would 1858fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// confuse EXPECT_DEATH gtest macro. 1868fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanytypedef char*(*PointerToStrChr1)(const char*, int); 1878fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanytypedef char*(*PointerToStrChr2)(char*, int); 1888fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 1892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesUNUSED static void RunStrChrTest(PointerToStrChr1 StrChr) { 1908fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t size = Ident(100); 1918fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *str = MallocAndMemsetString(size); 1928fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[10] = 'q'; 1938fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[11] = '\0'; 1948fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(str, StrChr(str, 'z')); 1958fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(str + 10, StrChr(str, 'q')); 1968fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(NULL, StrChr(str, 'a')); 1978fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // StrChr argument points to not allocated memory. 1988fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrChr(str - 1, 'z')), LeftOOBReadMessage(1)); 1998fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrChr(str + size, 'z')), RightOOBReadMessage(0)); 2008fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Overwrite the terminator and hit not allocated memory. 2018fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[11] = 'z'; 2028fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0)); 2038fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(str); 2048fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 2052d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesUNUSED static void RunStrChrTest(PointerToStrChr2 StrChr) { 2068fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t size = Ident(100); 2078fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *str = MallocAndMemsetString(size); 2088fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[10] = 'q'; 2098fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[11] = '\0'; 2108fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(str, StrChr(str, 'z')); 2118fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(str + 10, StrChr(str, 'q')); 2128fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(NULL, StrChr(str, 'a')); 2138fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // StrChr argument points to not allocated memory. 2148fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrChr(str - 1, 'z')), LeftOOBReadMessage(1)); 2158fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrChr(str + size, 'z')), RightOOBReadMessage(0)); 2168fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Overwrite the terminator and hit not allocated memory. 2178fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[11] = 'z'; 2188fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0)); 2198fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(str); 2208fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 2218fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 2228fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrChrAndIndexOOBTest) { 2238fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunStrChrTest(&strchr); 2246d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// No index() on Windows and on Android L. 2256d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if !defined(_WIN32) && !defined(__ANDROID__) 2268fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunStrChrTest(&index); 2272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 2288fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 2298fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 2308fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrCmpAndFriendsLogicTest) { 2318fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // strcmp 2328fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strcmp("", "")); 2338fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strcmp("abcd", "abcd")); 2348fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strcmp("ab", "ac")); 2358fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strcmp("abc", "abcd")); 2368fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strcmp("acc", "abc")); 2378fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strcmp("abcd", "abc")); 2388fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 2398fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // strncmp 2408fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strncmp("a", "b", 0)); 2418fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strncmp("abcd", "abcd", 10)); 2428fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strncmp("abcd", "abcef", 3)); 2438fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strncmp("abcde", "abcfa", 4)); 2448fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strncmp("a", "b", 5)); 2458fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strncmp("bc", "bcde", 4)); 2468fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strncmp("xyz", "xyy", 10)); 2478fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strncmp("baa", "aaa", 1)); 2488fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strncmp("zyx", "", 2)); 2498fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 2502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32) // no str[n]casecmp on Windows. 2518fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // strcasecmp 2528fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strcasecmp("", "")); 2538fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strcasecmp("zzz", "zzz")); 2548fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strcasecmp("abCD", "ABcd")); 2558fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strcasecmp("aB", "Ac")); 2568fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strcasecmp("ABC", "ABCd")); 2578fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strcasecmp("acc", "abc")); 2588fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strcasecmp("ABCd", "abc")); 2598fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 2608fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // strncasecmp 2618fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strncasecmp("a", "b", 0)); 2628fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strncasecmp("abCD", "ABcd", 10)); 2638fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strncasecmp("abCd", "ABcef", 3)); 2648fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strncasecmp("abcde", "ABCfa", 4)); 2658fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strncasecmp("a", "B", 5)); 2668fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strncasecmp("bc", "BCde", 4)); 2678fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strncasecmp("xyz", "xyy", 10)); 2688fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strncasecmp("Baa", "aaa", 1)); 2698fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strncasecmp("zyx", "", 2)); 2702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 2718fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 2728fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // memcmp 2738fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, memcmp("a", "b", 0)); 2748fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, memcmp("ab\0c", "ab\0c", 4)); 2758fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, memcmp("\0ab", "\0ac", 3)); 2768fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, memcmp("abb\0", "abba", 4)); 2778fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, memcmp("ab\0cd", "ab\0c\0", 5)); 2788fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, memcmp("zza", "zyx", 3)); 2798fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 2808fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 2818fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanytypedef int(*PointerToStrCmp)(const char*, const char*); 2828fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanyvoid RunStrCmpTest(PointerToStrCmp StrCmp) { 2838fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t size = Ident(100); 2848fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany int fill = 'o'; 2858fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *s1 = MallocAndMemsetString(size, fill); 2868fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *s2 = MallocAndMemsetString(size, fill); 2878fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s1[size - 1] = '\0'; 2888fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s2[size - 1] = '\0'; 2898fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal StrCmp calls 2908fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(StrCmp(s1, s2)); 2918fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(StrCmp(s1, s2 + size - 1)); 2928fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(StrCmp(s1 + size - 1, s2 + size - 1)); 2938fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // One of arguments points to not allocated memory. 2948fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrCmp)(s1 - 1, s2), LeftOOBReadMessage(1)); 2958fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrCmp)(s1, s2 - 1), LeftOOBReadMessage(1)); 2968fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrCmp)(s1 + size, s2), RightOOBReadMessage(0)); 2978fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrCmp)(s1, s2 + size), RightOOBReadMessage(0)); 2988fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Hit unallocated memory and die. 2998fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s1[size - 1] = fill; 3008fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrCmp)(s1, s1), RightOOBReadMessage(0)); 3018fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrCmp)(s1 + size - 1, s2), RightOOBReadMessage(0)); 3028fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(s1); 3038fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(s2); 3048fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 3058fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 3068fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrCmpOOBTest) { 3078fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunStrCmpTest(&strcmp); 3088fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 3098fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 3102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32) // no str[n]casecmp on Windows. 3118fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrCaseCmpOOBTest) { 3128fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunStrCmpTest(&strcasecmp); 3138fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 3142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 3158fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 3168fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanytypedef int(*PointerToStrNCmp)(const char*, const char*, size_t); 3178fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanyvoid RunStrNCmpTest(PointerToStrNCmp StrNCmp) { 3188fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t size = Ident(100); 3198fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *s1 = MallocAndMemsetString(size); 3208fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *s2 = MallocAndMemsetString(size); 3218fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s1[size - 1] = '\0'; 3228fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s2[size - 1] = '\0'; 3238fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal StrNCmp calls 3248fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(StrNCmp(s1, s2, size + 2)); 3258fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s1[size - 1] = 'z'; 3268fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s2[size - 1] = 'x'; 3278fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(StrNCmp(s1 + size - 2, s2 + size - 2, size)); 3288fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s2[size - 1] = 'z'; 3298fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(StrNCmp(s1 - 1, s2 - 1, 0)); 3308fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(StrNCmp(s1 + size - 1, s2 + size - 1, 1)); 3318fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // One of arguments points to not allocated memory. 3328fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrNCmp)(s1 - 1, s2, 1), LeftOOBReadMessage(1)); 3338fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrNCmp)(s1, s2 - 1, 1), LeftOOBReadMessage(1)); 3348fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrNCmp)(s1 + size, s2, 1), RightOOBReadMessage(0)); 3358fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrNCmp)(s1, s2 + size, 1), RightOOBReadMessage(0)); 3368fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Hit unallocated memory and die. 3378fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrNCmp)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0)); 3388fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrNCmp)(s1 + size - 1, s2, 2), RightOOBReadMessage(0)); 3398fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(s1); 3408fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(s2); 3418fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 3428fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 3438fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrNCmpOOBTest) { 3448fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunStrNCmpTest(&strncmp); 3458fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 3468fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 3472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32) // no str[n]casecmp on Windows. 3488fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrNCaseCmpOOBTest) { 3498fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunStrNCmpTest(&strncasecmp); 3508fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 3512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 3522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 3538fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrCatOOBTest) { 3548fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // strcat() reads strlen(to) bytes from |to| before concatenating. 3558fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t to_size = Ident(100); 3568fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *to = MallocAndMemsetString(to_size); 3578fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany to[0] = '\0'; 3588fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t from_size = Ident(20); 3598fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *from = MallocAndMemsetString(from_size); 3608fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany from[from_size - 1] = '\0'; 3618fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal strcat calls. 3628fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcat(to, from); 3638fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcat(to, from); 3648fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcat(to + from_size, from + from_size - 2); 3658fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Passing an invalid pointer is an error even when concatenating an empty 3668fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // string. 3678fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(to - 1, from + from_size - 1), LeftOOBAccessMessage(1)); 3688fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // One of arguments points to not allocated memory. 3698fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(to - 1, from), LeftOOBAccessMessage(1)); 3708fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(to, from - 1), LeftOOBReadMessage(1)); 3718fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(to, from + from_size), RightOOBReadMessage(0)); 3728fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 3738fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // "from" is not zero-terminated. 3748fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany from[from_size - 1] = 'z'; 3758fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(to, from), RightOOBReadMessage(0)); 3768fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany from[from_size - 1] = '\0'; 3778fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // "to" is too short to fit "from". 378909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar memset(to, 'z', to_size); 3798fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany to[to_size - from_size + 1] = '\0'; 3808fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(to, from), RightOOBWriteMessage(0)); 3818fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // length of "to" is just enough. 3828fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcat(to, from + 1); 3838fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 3848fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(to); 3858fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(from); 3868fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 3878fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 3888fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrNCatOOBTest) { 3898fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // strncat() reads strlen(to) bytes from |to| before concatenating. 3908fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t to_size = Ident(100); 3918fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *to = MallocAndMemsetString(to_size); 3928fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany to[0] = '\0'; 3938fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t from_size = Ident(20); 3948fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *from = MallocAndMemsetString(from_size); 3958fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal strncat calls. 3968fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncat(to, from, 0); 3978fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncat(to, from, from_size); 3988fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany from[from_size - 1] = '\0'; 3998fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncat(to, from, 2 * from_size); 4008fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Catenating empty string with an invalid string is still an error. 4018fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(to - 1, from, 0), LeftOOBAccessMessage(1)); 4028fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncat(to, from + from_size - 1, 10); 4038fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // One of arguments points to not allocated memory. 4048fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(to - 1, from, 2), LeftOOBAccessMessage(1)); 4058fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(to, from - 1, 2), LeftOOBReadMessage(1)); 4068fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(to, from + from_size, 2), RightOOBReadMessage(0)); 4078fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4088fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(from, 'z', from_size); 4098fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(to, 'z', to_size); 4108fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany to[0] = '\0'; 4118fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // "from" is too short. 4128fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(to, from, from_size + 1), RightOOBReadMessage(0)); 4138fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // "to" is too short to fit "from". 4148fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany to[0] = 'z'; 4158fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany to[to_size - from_size + 1] = '\0'; 4168fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(to, from, from_size - 1), RightOOBWriteMessage(0)); 4178fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // "to" is just enough. 4188fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncat(to, from, from_size - 2); 4198fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4208fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(to); 4218fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(from); 4228fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 4238fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4248fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanystatic string OverlapErrorMessage(const string &func) { 4258fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany return func + "-param-overlap"; 4268fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 4278fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4288fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrArgsOverlapTest) { 4298fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t size = Ident(100); 4308fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *str = Ident((char*)malloc(size)); 4318fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4328fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// Do not check memcpy() on OS X 10.7 and later, where it actually aliases 4338fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// memmove(). 4348fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany#if !defined(__APPLE__) || !defined(MAC_OS_X_VERSION_10_7) || \ 4358fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7) 4368fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Check "memcpy". Use Ident() to avoid inlining. 4378fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(str, 'z', size); 4388fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(memcpy)(str + 1, str + 11, 10); 4398fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(memcpy)(str, str, 0); 4408fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(memcpy)(str, str + 14, 15), OverlapErrorMessage("memcpy")); 4418fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(memcpy)(str + 14, str, 15), OverlapErrorMessage("memcpy")); 4428fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany#endif 4438fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4448fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // We do not treat memcpy with to==from as a bug. 4458fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // See http://llvm.org/bugs/show_bug.cgi?id=11763. 4468fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // EXPECT_DEATH(Ident(memcpy)(str + 20, str + 20, 1), 4478fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // OverlapErrorMessage("memcpy")); 4488fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4498fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Check "strcpy". 4508fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(str, 'z', size); 4518fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[9] = '\0'; 4528fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcpy(str + 10, str); 4538fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcpy(str + 9, str), OverlapErrorMessage("strcpy")); 4548fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcpy(str, str + 4), OverlapErrorMessage("strcpy")); 4558fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcpy(str, str + 5); 4568fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4578fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Check "strncpy". 4588fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(str, 'z', size); 4598fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(str, str + 10, 10); 4608fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncpy(str, str + 9, 10), OverlapErrorMessage("strncpy")); 4618fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncpy(str + 9, str, 10), OverlapErrorMessage("strncpy")); 4628fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[10] = '\0'; 4638fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(str + 11, str, 20); 4648fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncpy(str + 10, str, 20), OverlapErrorMessage("strncpy")); 4658fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4668fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Check "strcat". 4678fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(str, 'z', size); 4688fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[10] = '\0'; 4698fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[20] = '\0'; 4708fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcat(str, str + 10); 4718fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(str, str + 11), OverlapErrorMessage("strcat")); 4728fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[10] = '\0'; 4738fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcat(str + 11, str); 4748fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(str, str + 9), OverlapErrorMessage("strcat")); 4758fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(str + 9, str), OverlapErrorMessage("strcat")); 4768fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(str + 10, str), OverlapErrorMessage("strcat")); 4778fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4788fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Check "strncat". 4798fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(str, 'z', size); 4808fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[10] = '\0'; 4818fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncat(str, str + 10, 10); // from is empty 4828fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(str, str + 11, 10), OverlapErrorMessage("strncat")); 4838fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[10] = '\0'; 4848fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[20] = '\0'; 4858fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncat(str + 5, str, 5); 4868fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[10] = '\0'; 4878fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(str + 5, str, 6), OverlapErrorMessage("strncat")); 4888fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(str, str + 9, 10), OverlapErrorMessage("strncat")); 4898fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4908fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(str); 4918fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 4928fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4938fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanytypedef void(*PointerToCallAtoi)(const char*); 4948fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4958fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanyvoid RunAtoiOOBTest(PointerToCallAtoi Atoi) { 4968fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *array = MallocAndMemsetString(10, '1'); 4978fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Invalid pointer to the string. 4988fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Atoi(array + 11), RightOOBReadMessage(1)); 4998fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Atoi(array - 1), LeftOOBReadMessage(1)); 5008fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Die if a buffer doesn't have terminating NULL. 5018fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0)); 502909fff81b83df049ecc6e02407394640435d7befPirama Arumuga Nainar // Make last symbol a terminating NULL 5038fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[9] = '\0'; 5048fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Atoi(array); 5058fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Sometimes we need to detect overflow if no digits are found. 5068fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(array, ' ', 10); 5078fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0)); 5088fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[9] = '-'; 5098fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0)); 5108fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Atoi(array + 9), RightOOBReadMessage(0)); 5118fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(array); 5128fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 5138fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 5142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32) // FIXME: Fix and enable on Windows. 5156d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid CallAtoi(const char *nptr) { 5166d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Ident(atoi(nptr)); 5176d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 5186d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid CallAtol(const char *nptr) { 5196d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Ident(atol(nptr)); 5206d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 5216d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid CallAtoll(const char *nptr) { 5226d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Ident(atoll(nptr)); 5236d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 5248fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, AtoiAndFriendsOOBTest) { 5258fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunAtoiOOBTest(&CallAtoi); 5268fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunAtoiOOBTest(&CallAtol); 5278fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunAtoiOOBTest(&CallAtoll); 5288fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 5292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 5308fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 5318fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanytypedef void(*PointerToCallStrtol)(const char*, char**, int); 5328fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 5338fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanyvoid RunStrtolOOBTest(PointerToCallStrtol Strtol) { 5348fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *array = MallocAndMemsetString(3); 5358fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[0] = '1'; 5368fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[1] = '2'; 5378fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[2] = '3'; 5388fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Invalid pointer to the string. 5398fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Strtol(array + 3, NULL, 0), RightOOBReadMessage(0)); 5408fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Strtol(array - 1, NULL, 0), LeftOOBReadMessage(1)); 5418fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Buffer overflow if there is no terminating null (depends on base). 5428fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 5438fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[2] = 'z'; 5448fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Strtol(array, NULL, 36), RightOOBReadMessage(0)); 5458fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Add terminating zero to get rid of overflow. 5468fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[2] = '\0'; 5478fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Strtol(array, NULL, 36); 5488fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Sometimes we need to detect overflow if no digits are found. 5498fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[0] = array[1] = array[2] = ' '; 5508fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 5518fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[2] = '+'; 5528fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 5538fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[2] = '-'; 5548fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 5558fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(array); 5568fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 5578fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 5582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32) // FIXME: Fix and enable on Windows. 5596d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid CallStrtol(const char *nptr, char **endptr, int base) { 5606d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Ident(strtol(nptr, endptr, base)); 5616d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 5626d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid CallStrtoll(const char *nptr, char **endptr, int base) { 5636d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Ident(strtoll(nptr, endptr, base)); 5646d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 5658fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrtollOOBTest) { 5668fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunStrtolOOBTest(&CallStrtoll); 5678fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 5688fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrtolOOBTest) { 5698fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunStrtolOOBTest(&CallStrtol); 5708fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 5712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 5728fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 5738fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 574