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 23c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarconst char kStackReadUnderflow[] = 24c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if !GTEST_USES_SIMPLE_RE 25c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar ASAN_PCRE_DOTALL 26c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "READ.*" 27c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif 28c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "underflows this variable"; 29c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarconst char kStackReadOverflow[] = 30c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#if !GTEST_USES_SIMPLE_RE 31c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar ASAN_PCRE_DOTALL 32c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "READ.*" 33c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif 34c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar "overflows this variable"; 35c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 36c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarnamespace { 37c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarenum class OOBKind { 38c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Heap, 39c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Stack, 40c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar Global, 41c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}; 42c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 43c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstring LeftOOBReadMessage(OOBKind oob_kind, int oob_distance) { 44c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return oob_kind == OOBKind::Stack ? kStackReadUnderflow 45c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar : ::LeftOOBReadMessage(oob_distance); 46c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 47c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 48c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstring RightOOBReadMessage(OOBKind oob_kind, int oob_distance) { 49c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar return oob_kind == OOBKind::Stack ? kStackReadOverflow 50c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar : ::RightOOBReadMessage(oob_distance); 51c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 52c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} // namespace 53c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 548fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// Input to a test is a zero-terminated string str with given length 558fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// Accesses to the bytes to the left and to the right of str 568fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// are presumed to produce OOB errors 57c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarvoid StrLenOOBTestTemplate(char *str, size_t length, OOBKind oob_kind) { 588fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal strlen calls 598fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(strlen(str), length); 608fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany if (length > 0) { 618fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(length - 1, strlen(str + 1)); 628fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0U, strlen(str + length)); 638fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany } 648fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Arg of strlen is not malloced, OOB access 65c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar if (oob_kind != OOBKind::Global) { 668fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // We don't insert RedZones to the left of global variables 67c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar EXPECT_DEATH(Ident(strlen(str - 1)), LeftOOBReadMessage(oob_kind, 1)); 68c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar EXPECT_DEATH(Ident(strlen(str - 5)), LeftOOBReadMessage(oob_kind, 5)); 698fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany } 70c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar EXPECT_DEATH(Ident(strlen(str + length + 1)), 71c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar RightOOBReadMessage(oob_kind, 0)); 728fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Overwrite terminator 738fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[length] = 'a'; 748fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // String is not zero-terminated, strlen will lead to OOB access 75c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar EXPECT_DEATH(Ident(strlen(str)), RightOOBReadMessage(oob_kind, 0)); 76c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar EXPECT_DEATH(Ident(strlen(str + length)), RightOOBReadMessage(oob_kind, 0)); 778fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Restore terminator 788fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[length] = 0; 798fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 808fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrLenOOBTest) { 818fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Check heap-allocated string 828fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t length = Ident(10); 838fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *heap_string = Ident((char*)malloc(length + 1)); 848fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char stack_string[10 + 1]; 858fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany break_optimization(&stack_string); 868fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany for (size_t i = 0; i < length; i++) { 878fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany heap_string[i] = 'a'; 888fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany stack_string[i] = 'b'; 898fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany } 908fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany heap_string[length] = 0; 918fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany stack_string[length] = 0; 92c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar StrLenOOBTestTemplate(heap_string, length, OOBKind::Heap); 93c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar StrLenOOBTestTemplate(stack_string, length, OOBKind::Stack); 94c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar StrLenOOBTestTemplate(global_string, global_string_length, OOBKind::Global); 958fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(heap_string); 968fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 978fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 98b99228de65b408b0acd9618b92774fb8add7e482Reid KlecknerTEST(AddressSanitizer, WcsLenTest) { 99e9e4f04e8320d35ab19dfb8688a7bdd3e5ae7cbbAlexey Samsonov EXPECT_EQ(0U, wcslen(Ident(L""))); 100b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner size_t hello_len = 13; 101b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner size_t hello_size = (hello_len + 1) * sizeof(wchar_t); 102b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner EXPECT_EQ(hello_len, wcslen(Ident(L"Hello, World!"))); 103b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner wchar_t *heap_string = Ident((wchar_t*)malloc(hello_size)); 104b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner memcpy(heap_string, L"Hello, World!", hello_size); 105b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner EXPECT_EQ(hello_len, Ident(wcslen(heap_string))); 106b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner EXPECT_DEATH(Ident(wcslen(heap_string + 14)), RightOOBReadMessage(0)); 1071a249181dcdf217d368fbf4c1f09d8af7e617cb0Alexey Samsonov free(heap_string); 108b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner} 109b99228de65b408b0acd9618b92774fb8add7e482Reid Kleckner 1102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if SANITIZER_TEST_HAS_STRNLEN 1118fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrNLenOOBTest) { 1128fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t size = Ident(123); 1138fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *str = MallocAndMemsetString(size); 1148fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal strnlen calls. 1158fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(strnlen(str - 1, 0)); 1168fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(strnlen(str, size)); 1178fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(strnlen(str + size - 1, 1)); 1188fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[size - 1] = '\0'; 1198fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(strnlen(str, 2 * size)); 1208fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Argument points to not allocated memory. 1218fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strnlen(str - 1, 1)), LeftOOBReadMessage(1)); 1228fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strnlen(str + size, 1)), RightOOBReadMessage(0)); 1238fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Overwrite the terminating '\0' and hit unallocated memory. 1248fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[size - 1] = 'z'; 1258fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strnlen(str, size + 1)), RightOOBReadMessage(0)); 1268fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(str); 1278fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 1282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif // SANITIZER_TEST_HAS_STRNLEN 1298fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 1308fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrDupOOBTest) { 1318fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t size = Ident(42); 1328fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *str = MallocAndMemsetString(size); 1338fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *new_str; 1348fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal strdup calls. 1358fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[size - 1] = '\0'; 1368fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany new_str = strdup(str); 1378fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(new_str); 1388fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany new_str = strdup(str + size - 1); 1398fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(new_str); 1408fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Argument points to not allocated memory. 1418fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strdup(str - 1)), LeftOOBReadMessage(1)); 1428fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strdup(str + size)), RightOOBReadMessage(0)); 1438fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Overwrite the terminating '\0' and hit unallocated memory. 1448fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[size - 1] = 'z'; 1458fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strdup(str)), RightOOBReadMessage(0)); 1468fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(str); 1478fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 1488fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 1498fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrCpyOOBTest) { 1508fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t to_size = Ident(30); 1518fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t from_size = Ident(6); // less than to_size 1528fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *to = Ident((char*)malloc(to_size)); 1538fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *from = Ident((char*)malloc(from_size)); 1548fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal strcpy calls. 1558fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcpy(from, "hello"); 1568fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcpy(to, from); 1578fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcpy(to + to_size - from_size, from); 1588fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Length of "from" is too small. 1598fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strcpy(from, "hello2")), RightOOBWriteMessage(0)); 1608fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // "to" or "from" points to not allocated memory. 1618fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strcpy(to - 1, from)), LeftOOBWriteMessage(1)); 1628fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strcpy(to, from - 1)), LeftOOBReadMessage(1)); 1638fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strcpy(to, from + from_size)), RightOOBReadMessage(0)); 1648fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strcpy(to + to_size, from)), RightOOBWriteMessage(0)); 1658fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Overwrite the terminating '\0' character and hit unallocated memory. 1668fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany from[from_size - 1] = '!'; 1678fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strcpy(to, from)), RightOOBReadMessage(0)); 1688fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(to); 1698fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(from); 1708fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 1718fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 1728fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrNCpyOOBTest) { 1738fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t to_size = Ident(20); 1748fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t from_size = Ident(6); // less than to_size 1758fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *to = Ident((char*)malloc(to_size)); 1768fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // From is a zero-terminated string "hello\0" of length 6 1778fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *from = Ident((char*)malloc(from_size)); 1788fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcpy(from, "hello"); 1798fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // copy 0 bytes 1808fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(to, from, 0); 1818fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(to - 1, from - 1, 0); 1828fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // normal strncpy calls 1838fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(to, from, from_size); 1848fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(to, from, to_size); 1858fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(to, from + from_size - 1, to_size); 1868fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(to + to_size - 1, from, 1); 1878fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // One of {to, from} points to not allocated memory 1888fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strncpy(to, from - 1, from_size)), 1898fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany LeftOOBReadMessage(1)); 1908fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strncpy(to - 1, from, from_size)), 1918fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany LeftOOBWriteMessage(1)); 1928fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strncpy(to, from + from_size, 1)), 1938fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RightOOBReadMessage(0)); 1948fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strncpy(to + to_size, from, 1)), 1958fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RightOOBWriteMessage(0)); 1968fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Length of "to" is too small 1978fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strncpy(to + to_size - from_size + 1, from, from_size)), 1988fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RightOOBWriteMessage(0)); 1998fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strncpy(to + 1, from, to_size)), 2008fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RightOOBWriteMessage(0)); 2018fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Overwrite terminator in from 2028fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany from[from_size - 1] = '!'; 2038fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // normal strncpy call 2048fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(to, from, from_size); 2058fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Length of "from" is too small 2068fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(strncpy(to, from, to_size)), 2078fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RightOOBReadMessage(0)); 2088fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(to); 2098fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(from); 2108fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 2118fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 2128fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// Users may have different definitions of "strchr" and "index", so provide 2138fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// function pointer typedefs and overload RunStrChrTest implementation. 2148fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// We can't use macro for RunStrChrTest body here, as this macro would 2158fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// confuse EXPECT_DEATH gtest macro. 2168fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanytypedef char*(*PointerToStrChr1)(const char*, int); 2178fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanytypedef char*(*PointerToStrChr2)(char*, int); 2188fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 219c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainartemplate<typename StrChrFn> 220c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarstatic void RunStrChrTestImpl(StrChrFn *StrChr) { 2218fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t size = Ident(100); 2228fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *str = MallocAndMemsetString(size); 2238fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[10] = 'q'; 2248fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[11] = '\0'; 2258fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(str, StrChr(str, 'z')); 2268fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(str + 10, StrChr(str, 'q')); 2278fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(NULL, StrChr(str, 'a')); 2288fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // StrChr argument points to not allocated memory. 2298fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrChr(str - 1, 'z')), LeftOOBReadMessage(1)); 2308fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrChr(str + size, 'z')), RightOOBReadMessage(0)); 2318fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Overwrite the terminator and hit not allocated memory. 2328fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[11] = 'z'; 2338fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0)); 2348fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(str); 2358fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 236c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar 237c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// Prefer to use the standard signature if both are available. 238c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarUNUSED static void RunStrChrTest(PointerToStrChr1 StrChr, ...) { 239c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar RunStrChrTestImpl(StrChr); 240c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar} 241c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga NainarUNUSED static void RunStrChrTest(PointerToStrChr2 StrChr, int) { 242c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar RunStrChrTestImpl(StrChr); 2438fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 2448fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 2458fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrChrAndIndexOOBTest) { 246c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar RunStrChrTest(&strchr, 0); 2476d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// No index() on Windows and on Android L. 2486d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#if !defined(_WIN32) && !defined(__ANDROID__) 249c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar RunStrChrTest(&index, 0); 2502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 2518fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 2528fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 2538fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrCmpAndFriendsLogicTest) { 2548fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // strcmp 2558fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strcmp("", "")); 2568fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strcmp("abcd", "abcd")); 2578fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strcmp("ab", "ac")); 2588fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strcmp("abc", "abcd")); 2598fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strcmp("acc", "abc")); 2608fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strcmp("abcd", "abc")); 2618fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 2628fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // strncmp 2638fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strncmp("a", "b", 0)); 2648fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strncmp("abcd", "abcd", 10)); 2658fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strncmp("abcd", "abcef", 3)); 2668fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strncmp("abcde", "abcfa", 4)); 2678fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strncmp("a", "b", 5)); 2688fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strncmp("bc", "bcde", 4)); 2698fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strncmp("xyz", "xyy", 10)); 2708fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strncmp("baa", "aaa", 1)); 2718fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strncmp("zyx", "", 2)); 2728fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 2732d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32) // no str[n]casecmp on Windows. 2748fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // strcasecmp 2758fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strcasecmp("", "")); 2768fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strcasecmp("zzz", "zzz")); 2778fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strcasecmp("abCD", "ABcd")); 2788fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strcasecmp("aB", "Ac")); 2798fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strcasecmp("ABC", "ABCd")); 2808fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strcasecmp("acc", "abc")); 2818fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strcasecmp("ABCd", "abc")); 2828fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 2838fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // strncasecmp 2848fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strncasecmp("a", "b", 0)); 2858fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strncasecmp("abCD", "ABcd", 10)); 2868fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, strncasecmp("abCd", "ABcef", 3)); 2878fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strncasecmp("abcde", "ABCfa", 4)); 2888fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strncasecmp("a", "B", 5)); 2898fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, strncasecmp("bc", "BCde", 4)); 2908fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strncasecmp("xyz", "xyy", 10)); 2918fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strncasecmp("Baa", "aaa", 1)); 2928fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, strncasecmp("zyx", "", 2)); 2932d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 2948fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 2958fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // memcmp 2968fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, memcmp("a", "b", 0)); 2978fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_EQ(0, memcmp("ab\0c", "ab\0c", 4)); 2988fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, memcmp("\0ab", "\0ac", 3)); 2998fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_GT(0, memcmp("abb\0", "abba", 4)); 3008fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, memcmp("ab\0cd", "ab\0c\0", 5)); 3018fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_LT(0, memcmp("zza", "zyx", 3)); 3028fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 3038fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 3048fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanytypedef int(*PointerToStrCmp)(const char*, const char*); 3058fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanyvoid RunStrCmpTest(PointerToStrCmp StrCmp) { 3068fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t size = Ident(100); 3078fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany int fill = 'o'; 3088fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *s1 = MallocAndMemsetString(size, fill); 3098fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *s2 = MallocAndMemsetString(size, fill); 3108fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s1[size - 1] = '\0'; 3118fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s2[size - 1] = '\0'; 3128fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal StrCmp calls 3138fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(StrCmp(s1, s2)); 3148fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(StrCmp(s1, s2 + size - 1)); 3158fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(StrCmp(s1 + size - 1, s2 + size - 1)); 3168fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // One of arguments points to not allocated memory. 3178fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrCmp)(s1 - 1, s2), LeftOOBReadMessage(1)); 3188fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrCmp)(s1, s2 - 1), LeftOOBReadMessage(1)); 3198fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrCmp)(s1 + size, s2), RightOOBReadMessage(0)); 3208fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrCmp)(s1, s2 + size), RightOOBReadMessage(0)); 3218fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Hit unallocated memory and die. 3228fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s1[size - 1] = fill; 3238fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrCmp)(s1, s1), RightOOBReadMessage(0)); 3248fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrCmp)(s1 + size - 1, s2), RightOOBReadMessage(0)); 3258fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(s1); 3268fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(s2); 3278fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 3288fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 3298fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrCmpOOBTest) { 3308fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunStrCmpTest(&strcmp); 3318fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 3328fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 3332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32) // no str[n]casecmp on Windows. 3348fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrCaseCmpOOBTest) { 3358fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunStrCmpTest(&strcasecmp); 3368fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 3372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 3388fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 3398fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanytypedef int(*PointerToStrNCmp)(const char*, const char*, size_t); 3408fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanyvoid RunStrNCmpTest(PointerToStrNCmp StrNCmp) { 3418fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t size = Ident(100); 3428fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *s1 = MallocAndMemsetString(size); 3438fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *s2 = MallocAndMemsetString(size); 3448fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s1[size - 1] = '\0'; 3458fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s2[size - 1] = '\0'; 3468fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal StrNCmp calls 3478fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(StrNCmp(s1, s2, size + 2)); 3488fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s1[size - 1] = 'z'; 3498fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s2[size - 1] = 'x'; 3508fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(StrNCmp(s1 + size - 2, s2 + size - 2, size)); 3518fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany s2[size - 1] = 'z'; 3528fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(StrNCmp(s1 - 1, s2 - 1, 0)); 3538fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(StrNCmp(s1 + size - 1, s2 + size - 1, 1)); 3548fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // One of arguments points to not allocated memory. 3558fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrNCmp)(s1 - 1, s2, 1), LeftOOBReadMessage(1)); 3568fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrNCmp)(s1, s2 - 1, 1), LeftOOBReadMessage(1)); 3578fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrNCmp)(s1 + size, s2, 1), RightOOBReadMessage(0)); 3588fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrNCmp)(s1, s2 + size, 1), RightOOBReadMessage(0)); 3598fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Hit unallocated memory and die. 3608fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrNCmp)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0)); 3618fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(StrNCmp)(s1 + size - 1, s2, 2), RightOOBReadMessage(0)); 3628fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(s1); 3638fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(s2); 3648fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 3658fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 3668fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrNCmpOOBTest) { 3678fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunStrNCmpTest(&strncmp); 3688fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 3698fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 3702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32) // no str[n]casecmp on Windows. 3718fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrNCaseCmpOOBTest) { 3728fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunStrNCmpTest(&strncasecmp); 3738fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 3742d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 3752d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 3768fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrCatOOBTest) { 3778fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // strcat() reads strlen(to) bytes from |to| before concatenating. 3788fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t to_size = Ident(100); 3798fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *to = MallocAndMemsetString(to_size); 3808fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany to[0] = '\0'; 3818fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t from_size = Ident(20); 3828fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *from = MallocAndMemsetString(from_size); 3838fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany from[from_size - 1] = '\0'; 3848fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal strcat calls. 3858fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcat(to, from); 3868fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcat(to, from); 3878fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcat(to + from_size, from + from_size - 2); 3888fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Passing an invalid pointer is an error even when concatenating an empty 3898fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // string. 3908fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(to - 1, from + from_size - 1), LeftOOBAccessMessage(1)); 3918fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // One of arguments points to not allocated memory. 3928fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(to - 1, from), LeftOOBAccessMessage(1)); 3938fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(to, from - 1), LeftOOBReadMessage(1)); 3948fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(to, from + from_size), RightOOBReadMessage(0)); 3958fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 3968fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // "from" is not zero-terminated. 3978fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany from[from_size - 1] = 'z'; 3988fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(to, from), RightOOBReadMessage(0)); 3998fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany from[from_size - 1] = '\0'; 4008fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // "to" is too short to fit "from". 401259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar memset(to, 'z', to_size); 4028fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany to[to_size - from_size + 1] = '\0'; 4038fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(to, from), RightOOBWriteMessage(0)); 4048fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // length of "to" is just enough. 4058fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcat(to, from + 1); 4068fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4078fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(to); 4088fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(from); 4098fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 4108fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4118fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrNCatOOBTest) { 4128fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // strncat() reads strlen(to) bytes from |to| before concatenating. 4138fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t to_size = Ident(100); 4148fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *to = MallocAndMemsetString(to_size); 4158fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany to[0] = '\0'; 4168fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t from_size = Ident(20); 4178fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *from = MallocAndMemsetString(from_size); 4188fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Normal strncat calls. 4198fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncat(to, from, 0); 4208fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncat(to, from, from_size); 4218fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany from[from_size - 1] = '\0'; 4228fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncat(to, from, 2 * from_size); 4238fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Catenating empty string with an invalid string is still an error. 4248fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(to - 1, from, 0), LeftOOBAccessMessage(1)); 4258fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncat(to, from + from_size - 1, 10); 4268fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // One of arguments points to not allocated memory. 4278fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(to - 1, from, 2), LeftOOBAccessMessage(1)); 4288fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(to, from - 1, 2), LeftOOBReadMessage(1)); 4298fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(to, from + from_size, 2), RightOOBReadMessage(0)); 4308fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4318fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(from, 'z', from_size); 4328fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(to, 'z', to_size); 4338fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany to[0] = '\0'; 4348fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // "from" is too short. 4358fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(to, from, from_size + 1), RightOOBReadMessage(0)); 4368fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // "to" is too short to fit "from". 4378fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany to[0] = 'z'; 4388fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany to[to_size - from_size + 1] = '\0'; 4398fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(to, from, from_size - 1), RightOOBWriteMessage(0)); 4408fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // "to" is just enough. 4418fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncat(to, from, from_size - 2); 4428fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4438fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(to); 4448fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(from); 4458fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 4468fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4478fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanystatic string OverlapErrorMessage(const string &func) { 4488fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany return func + "-param-overlap"; 4498fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 4508fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4518fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrArgsOverlapTest) { 4528fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany size_t size = Ident(100); 4538fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *str = Ident((char*)malloc(size)); 4548fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4558fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// Do not check memcpy() on OS X 10.7 and later, where it actually aliases 4568fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany// memmove(). 4578fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany#if !defined(__APPLE__) || !defined(MAC_OS_X_VERSION_10_7) || \ 4588fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7) 4598fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Check "memcpy". Use Ident() to avoid inlining. 4608fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(str, 'z', size); 4618fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(memcpy)(str + 1, str + 11, 10); 4628fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Ident(memcpy)(str, str, 0); 4638fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(memcpy)(str, str + 14, 15), OverlapErrorMessage("memcpy")); 4648fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Ident(memcpy)(str + 14, str, 15), OverlapErrorMessage("memcpy")); 4658fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany#endif 4668fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4678fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // We do not treat memcpy with to==from as a bug. 4688fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // See http://llvm.org/bugs/show_bug.cgi?id=11763. 4698fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // EXPECT_DEATH(Ident(memcpy)(str + 20, str + 20, 1), 4708fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // OverlapErrorMessage("memcpy")); 4718fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4728fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Check "strcpy". 4738fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(str, 'z', size); 4748fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[9] = '\0'; 4758fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcpy(str + 10, str); 4768fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcpy(str + 9, str), OverlapErrorMessage("strcpy")); 4778fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcpy(str, str + 4), OverlapErrorMessage("strcpy")); 4788fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcpy(str, str + 5); 4798fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4808fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Check "strncpy". 4818fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(str, 'z', size); 4828fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(str, str + 10, 10); 4838fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncpy(str, str + 9, 10), OverlapErrorMessage("strncpy")); 4848fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncpy(str + 9, str, 10), OverlapErrorMessage("strncpy")); 4858fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[10] = '\0'; 4868fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncpy(str + 11, str, 20); 4878fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncpy(str + 10, str, 20), OverlapErrorMessage("strncpy")); 4888fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 4898fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Check "strcat". 4908fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(str, 'z', size); 4918fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[10] = '\0'; 4928fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[20] = '\0'; 4938fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcat(str, str + 10); 4948fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(str, str + 11), OverlapErrorMessage("strcat")); 4958fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[10] = '\0'; 4968fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strcat(str + 11, str); 4978fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(str, str + 9), OverlapErrorMessage("strcat")); 4988fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(str + 9, str), OverlapErrorMessage("strcat")); 4998fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strcat(str + 10, str), OverlapErrorMessage("strcat")); 5008fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 5018fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Check "strncat". 5028fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(str, 'z', size); 5038fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[10] = '\0'; 5048fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncat(str, str + 10, 10); // from is empty 5058fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(str, str + 11, 10), OverlapErrorMessage("strncat")); 5068fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[10] = '\0'; 5078fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[20] = '\0'; 5088fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany strncat(str + 5, str, 5); 5098fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany str[10] = '\0'; 5108fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(str + 5, str, 6), OverlapErrorMessage("strncat")); 5118fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(strncat(str, str + 9, 10), OverlapErrorMessage("strncat")); 5128fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 5138fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(str); 5148fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 5158fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 5168fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanytypedef void(*PointerToCallAtoi)(const char*); 5178fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 5188fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanyvoid RunAtoiOOBTest(PointerToCallAtoi Atoi) { 5198fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *array = MallocAndMemsetString(10, '1'); 5208fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Invalid pointer to the string. 5218fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Atoi(array + 11), RightOOBReadMessage(1)); 5228fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Atoi(array - 1), LeftOOBReadMessage(1)); 5238fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Die if a buffer doesn't have terminating NULL. 5248fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0)); 525259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar // Make last symbol a terminating NULL 5268fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[9] = '\0'; 5278fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Atoi(array); 5288fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Sometimes we need to detect overflow if no digits are found. 5298fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany memset(array, ' ', 10); 5308fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0)); 5318fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[9] = '-'; 5328fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0)); 5338fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Atoi(array + 9), RightOOBReadMessage(0)); 5348fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(array); 5358fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 5368fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 5372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32) // FIXME: Fix and enable on Windows. 5386d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid CallAtoi(const char *nptr) { 5396d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Ident(atoi(nptr)); 5406d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 5416d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid CallAtol(const char *nptr) { 5426d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Ident(atol(nptr)); 5436d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 5446d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid CallAtoll(const char *nptr) { 5456d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Ident(atoll(nptr)); 5466d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 5478fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, AtoiAndFriendsOOBTest) { 5488fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunAtoiOOBTest(&CallAtoi); 5498fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunAtoiOOBTest(&CallAtol); 5508fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunAtoiOOBTest(&CallAtoll); 5518fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 5522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 5538fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 5548fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanytypedef void(*PointerToCallStrtol)(const char*, char**, int); 5558fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 5568fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryanyvoid RunStrtolOOBTest(PointerToCallStrtol Strtol) { 5578fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany char *array = MallocAndMemsetString(3); 5588fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[0] = '1'; 5598fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[1] = '2'; 5608fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[2] = '3'; 5618fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Invalid pointer to the string. 5628fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Strtol(array + 3, NULL, 0), RightOOBReadMessage(0)); 5638fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Strtol(array - 1, NULL, 0), LeftOOBReadMessage(1)); 5648fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Buffer overflow if there is no terminating null (depends on base). 5658fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 5668fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[2] = 'z'; 5678fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Strtol(array, NULL, 36), RightOOBReadMessage(0)); 5688fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Add terminating zero to get rid of overflow. 5698fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[2] = '\0'; 5708fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany Strtol(array, NULL, 36); 5718fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany // Sometimes we need to detect overflow if no digits are found. 5728fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[0] = array[1] = array[2] = ' '; 5738fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 5748fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[2] = '+'; 5758fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 5768fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany array[2] = '-'; 5778fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0)); 5788fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany free(array); 5798fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 5808fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 5812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#if !defined(_WIN32) // FIXME: Fix and enable on Windows. 5826d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid CallStrtol(const char *nptr, char **endptr, int base) { 5836d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Ident(strtol(nptr, endptr, base)); 5846d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 5856d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid CallStrtoll(const char *nptr, char **endptr, int base) { 5866d1862363c88c183b0ed7740fca876342cf0474bStephen Hines Ident(strtoll(nptr, endptr, base)); 5876d1862363c88c183b0ed7740fca876342cf0474bStephen Hines} 5888fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrtollOOBTest) { 5898fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunStrtolOOBTest(&CallStrtoll); 5908fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 5918fb1264341c079eda3e10480fb807a0f52bb8b19Kostya SerebryanyTEST(AddressSanitizer, StrtolOOBTest) { 5928fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany RunStrtolOOBTest(&CallStrtol); 5938fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany} 5942d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif 5958fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 5968fb1264341c079eda3e10480fb807a0f52bb8b19Kostya Serebryany 597