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