1*7c3d14c8STreehugger Robot // Test strict_string_checks option in strtoll function
2*7c3d14c8STreehugger Robot // RUN: %clang_asan %s -o %t
3*7c3d14c8STreehugger Robot // RUN: %run %t test1 2>&1
4*7c3d14c8STreehugger Robot // RUN: %env_asan_opts=strict_string_checks=false %run %t test1 2>&1
5*7c3d14c8STreehugger Robot // RUN: %env_asan_opts=strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1
6*7c3d14c8STreehugger Robot // RUN: %run %t test2 2>&1
7*7c3d14c8STreehugger Robot // RUN: %env_asan_opts=strict_string_checks=false %run %t test2 2>&1
8*7c3d14c8STreehugger Robot // RUN: %env_asan_opts=strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2
9*7c3d14c8STreehugger Robot // RUN: %run %t test3 2>&1
10*7c3d14c8STreehugger Robot // RUN: %env_asan_opts=strict_string_checks=false %run %t test3 2>&1
11*7c3d14c8STreehugger Robot // RUN: %env_asan_opts=strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3
12*7c3d14c8STreehugger Robot // RUN: %run %t test4 2>&1
13*7c3d14c8STreehugger Robot // RUN: %env_asan_opts=strict_string_checks=false %run %t test4 2>&1
14*7c3d14c8STreehugger Robot // RUN: %env_asan_opts=strict_string_checks=true not %run %t test4 2>&1 | FileCheck %s --check-prefix=CHECK4
15*7c3d14c8STreehugger Robot // RUN: %run %t test5 2>&1
16*7c3d14c8STreehugger Robot // RUN: %env_asan_opts=strict_string_checks=false %run %t test5 2>&1
17*7c3d14c8STreehugger Robot // RUN: %env_asan_opts=strict_string_checks=true not %run %t test5 2>&1 | FileCheck %s --check-prefix=CHECK5
18*7c3d14c8STreehugger Robot // RUN: %run %t test6 2>&1
19*7c3d14c8STreehugger Robot // RUN: %env_asan_opts=strict_string_checks=false %run %t test6 2>&1
20*7c3d14c8STreehugger Robot // RUN: %env_asan_opts=strict_string_checks=true not %run %t test6 2>&1 | FileCheck %s --check-prefix=CHECK6
21*7c3d14c8STreehugger Robot // RUN: %run %t test7 2>&1
22*7c3d14c8STreehugger Robot // RUN: %env_asan_opts=strict_string_checks=false %run %t test7 2>&1
23*7c3d14c8STreehugger Robot // RUN: %env_asan_opts=strict_string_checks=true not %run %t test7 2>&1 | FileCheck %s --check-prefix=CHECK7
24*7c3d14c8STreehugger Robot
25*7c3d14c8STreehugger Robot // FIXME: Enable strtoll interceptor.
26*7c3d14c8STreehugger Robot // XFAIL: win32
27*7c3d14c8STreehugger Robot
28*7c3d14c8STreehugger Robot #include <assert.h>
29*7c3d14c8STreehugger Robot #include <stdlib.h>
30*7c3d14c8STreehugger Robot #include <string.h>
31*7c3d14c8STreehugger Robot #include <sanitizer/asan_interface.h>
32*7c3d14c8STreehugger Robot
test1(char * array,char * endptr)33*7c3d14c8STreehugger Robot void test1(char *array, char *endptr) {
34*7c3d14c8STreehugger Robot // Buffer overflow if there is no terminating null (depends on base)
35*7c3d14c8STreehugger Robot long long r = strtoll(array, &endptr, 3);
36*7c3d14c8STreehugger Robot assert(array + 2 == endptr);
37*7c3d14c8STreehugger Robot assert(r == 5);
38*7c3d14c8STreehugger Robot }
39*7c3d14c8STreehugger Robot
test2(char * array,char * endptr)40*7c3d14c8STreehugger Robot void test2(char *array, char *endptr) {
41*7c3d14c8STreehugger Robot // Buffer overflow if there is no terminating null (depends on base)
42*7c3d14c8STreehugger Robot array[2] = 'z';
43*7c3d14c8STreehugger Robot long long r = strtoll(array, &endptr, 35);
44*7c3d14c8STreehugger Robot assert(array + 2 == endptr);
45*7c3d14c8STreehugger Robot assert(r == 37);
46*7c3d14c8STreehugger Robot }
47*7c3d14c8STreehugger Robot
test3(char * array,char * endptr)48*7c3d14c8STreehugger Robot void test3(char *array, char *endptr) {
49*7c3d14c8STreehugger Robot // Buffer overflow if base is invalid.
50*7c3d14c8STreehugger Robot memset(array, 0, 8);
51*7c3d14c8STreehugger Robot ASAN_POISON_MEMORY_REGION(array, 8);
52*7c3d14c8STreehugger Robot long long r = strtoll(array + 1, NULL, -1);
53*7c3d14c8STreehugger Robot assert(r == 0);
54*7c3d14c8STreehugger Robot ASAN_UNPOISON_MEMORY_REGION(array, 8);
55*7c3d14c8STreehugger Robot }
56*7c3d14c8STreehugger Robot
test4(char * array,char * endptr)57*7c3d14c8STreehugger Robot void test4(char *array, char *endptr) {
58*7c3d14c8STreehugger Robot // Buffer overflow if base is invalid.
59*7c3d14c8STreehugger Robot long long r = strtoll(array + 3, NULL, 1);
60*7c3d14c8STreehugger Robot assert(r == 0);
61*7c3d14c8STreehugger Robot }
62*7c3d14c8STreehugger Robot
test5(char * array,char * endptr)63*7c3d14c8STreehugger Robot void test5(char *array, char *endptr) {
64*7c3d14c8STreehugger Robot // Overflow if no digits are found.
65*7c3d14c8STreehugger Robot array[0] = ' ';
66*7c3d14c8STreehugger Robot array[1] = '+';
67*7c3d14c8STreehugger Robot array[2] = '-';
68*7c3d14c8STreehugger Robot long long r = strtoll(array, NULL, 0);
69*7c3d14c8STreehugger Robot assert(r == 0);
70*7c3d14c8STreehugger Robot }
71*7c3d14c8STreehugger Robot
test6(char * array,char * endptr)72*7c3d14c8STreehugger Robot void test6(char *array, char *endptr) {
73*7c3d14c8STreehugger Robot // Overflow if no digits are found.
74*7c3d14c8STreehugger Robot array[0] = ' ';
75*7c3d14c8STreehugger Robot array[1] = array[2] = 'z';
76*7c3d14c8STreehugger Robot long long r = strtoll(array, &endptr, 0);
77*7c3d14c8STreehugger Robot assert(array == endptr);
78*7c3d14c8STreehugger Robot assert(r == 0);
79*7c3d14c8STreehugger Robot }
80*7c3d14c8STreehugger Robot
test7(char * array,char * endptr)81*7c3d14c8STreehugger Robot void test7(char *array, char *endptr) {
82*7c3d14c8STreehugger Robot // Overflow if no digits are found.
83*7c3d14c8STreehugger Robot array[2] = 'z';
84*7c3d14c8STreehugger Robot long long r = strtoll(array + 2, NULL, 0);
85*7c3d14c8STreehugger Robot assert(r == 0);
86*7c3d14c8STreehugger Robot }
87*7c3d14c8STreehugger Robot
main(int argc,char ** argv)88*7c3d14c8STreehugger Robot int main(int argc, char **argv) {
89*7c3d14c8STreehugger Robot char *array0 = (char*)malloc(11);
90*7c3d14c8STreehugger Robot char* array = array0 + 8;
91*7c3d14c8STreehugger Robot char *endptr = NULL;
92*7c3d14c8STreehugger Robot array[0] = '1';
93*7c3d14c8STreehugger Robot array[1] = '2';
94*7c3d14c8STreehugger Robot array[2] = '3';
95*7c3d14c8STreehugger Robot if (argc != 2) return 1;
96*7c3d14c8STreehugger Robot if (!strcmp(argv[1], "test1")) test1(array, endptr);
97*7c3d14c8STreehugger Robot // CHECK1: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
98*7c3d14c8STreehugger Robot // CHECK1: READ of size 4
99*7c3d14c8STreehugger Robot if (!strcmp(argv[1], "test2")) test2(array, endptr);
100*7c3d14c8STreehugger Robot // CHECK2: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
101*7c3d14c8STreehugger Robot // CHECK2: READ of size 4
102*7c3d14c8STreehugger Robot if (!strcmp(argv[1], "test3")) test3(array0, endptr);
103*7c3d14c8STreehugger Robot // CHECK3: {{.*ERROR: AddressSanitizer: use-after-poison on address}}
104*7c3d14c8STreehugger Robot // CHECK3: READ of size 1
105*7c3d14c8STreehugger Robot if (!strcmp(argv[1], "test4")) test4(array, endptr);
106*7c3d14c8STreehugger Robot // CHECK4: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
107*7c3d14c8STreehugger Robot // CHECK4: READ of size 1
108*7c3d14c8STreehugger Robot if (!strcmp(argv[1], "test5")) test5(array, endptr);
109*7c3d14c8STreehugger Robot // CHECK5: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
110*7c3d14c8STreehugger Robot // CHECK5: READ of size 4
111*7c3d14c8STreehugger Robot if (!strcmp(argv[1], "test6")) test6(array, endptr);
112*7c3d14c8STreehugger Robot // CHECK6: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
113*7c3d14c8STreehugger Robot // CHECK6: READ of size 4
114*7c3d14c8STreehugger Robot if (!strcmp(argv[1], "test7")) test7(array, endptr);
115*7c3d14c8STreehugger Robot // CHECK7: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
116*7c3d14c8STreehugger Robot // CHECK7: READ of size 2
117*7c3d14c8STreehugger Robot free(array0);
118*7c3d14c8STreehugger Robot return 0;
119*7c3d14c8STreehugger Robot }
120