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