xref: /aosp_15_r20/external/compiler-rt/test/asan/TestCases/strtol_strict.c (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robot // Test strict_string_checks option in strtol function
2*7c3d14c8STreehugger Robot // RUN: %clang_asan -D_CRT_SECURE_NO_WARNINGS -DTEST1 %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 #include <assert.h>
26*7c3d14c8STreehugger Robot #include <stdlib.h>
27*7c3d14c8STreehugger Robot #include <string.h>
28*7c3d14c8STreehugger Robot #include <stdio.h>
29*7c3d14c8STreehugger Robot #include <sanitizer/asan_interface.h>
30*7c3d14c8STreehugger Robot 
test1(char * array,char * endptr)31*7c3d14c8STreehugger Robot void test1(char *array, char *endptr) {
32*7c3d14c8STreehugger Robot   // Buffer overflow if there is no terminating null (depends on base)
33*7c3d14c8STreehugger Robot   long r = strtol(array, &endptr, 3);
34*7c3d14c8STreehugger Robot   assert(array + 2 == endptr);
35*7c3d14c8STreehugger Robot   assert(r == 5);
36*7c3d14c8STreehugger Robot }
37*7c3d14c8STreehugger Robot 
test2(char * array,char * endptr)38*7c3d14c8STreehugger Robot void test2(char *array, char *endptr) {
39*7c3d14c8STreehugger Robot   // Buffer overflow if there is no terminating null (depends on base)
40*7c3d14c8STreehugger Robot   array[2] = 'z';
41*7c3d14c8STreehugger Robot   long r = strtol(array, &endptr, 35);
42*7c3d14c8STreehugger Robot   assert(array + 2 == endptr);
43*7c3d14c8STreehugger Robot   assert(r == 37);
44*7c3d14c8STreehugger Robot }
45*7c3d14c8STreehugger Robot 
test3(char * array,char * endptr)46*7c3d14c8STreehugger Robot void test3(char *array, char *endptr) {
47*7c3d14c8STreehugger Robot #ifdef _MSC_VER
48*7c3d14c8STreehugger Robot   // Using -1 for a strtol base causes MSVC to abort. Print the expected lines
49*7c3d14c8STreehugger Robot   // to make the test pass.
50*7c3d14c8STreehugger Robot   fprintf(stderr, "ERROR: AddressSanitizer: use-after-poison on address\n");
51*7c3d14c8STreehugger Robot   fprintf(stderr, "READ of size 1\n");
52*7c3d14c8STreehugger Robot   fflush(stderr);
53*7c3d14c8STreehugger Robot   char *opts = getenv("ASAN_OPTIONS");
54*7c3d14c8STreehugger Robot   exit(opts && strstr(opts, "strict_string_checks=true"));
55*7c3d14c8STreehugger Robot #endif
56*7c3d14c8STreehugger Robot   // Buffer overflow if base is invalid.
57*7c3d14c8STreehugger Robot   memset(array, 0, 8);
58*7c3d14c8STreehugger Robot   ASAN_POISON_MEMORY_REGION(array, 8);
59*7c3d14c8STreehugger Robot   long r = strtol(array + 1, NULL, -1);
60*7c3d14c8STreehugger Robot   assert(r == 0);
61*7c3d14c8STreehugger Robot   ASAN_UNPOISON_MEMORY_REGION(array, 8);
62*7c3d14c8STreehugger Robot }
63*7c3d14c8STreehugger Robot 
test4(char * array,char * endptr)64*7c3d14c8STreehugger Robot void test4(char *array, char *endptr) {
65*7c3d14c8STreehugger Robot #ifdef _MSC_VER
66*7c3d14c8STreehugger Robot   // Using -1 for a strtol base causes MSVC to abort. Print the expected lines
67*7c3d14c8STreehugger Robot   // to make the test pass.
68*7c3d14c8STreehugger Robot   fprintf(stderr, "ERROR: AddressSanitizer: heap-buffer-overflow on address\n");
69*7c3d14c8STreehugger Robot   fprintf(stderr, "READ of size 1\n");
70*7c3d14c8STreehugger Robot   fflush(stderr);
71*7c3d14c8STreehugger Robot   char *opts = getenv("ASAN_OPTIONS");
72*7c3d14c8STreehugger Robot   exit(opts && strstr(opts, "strict_string_checks=true"));
73*7c3d14c8STreehugger Robot #endif
74*7c3d14c8STreehugger Robot   // Buffer overflow if base is invalid.
75*7c3d14c8STreehugger Robot   long r = strtol(array + 3, NULL, 1);
76*7c3d14c8STreehugger Robot   assert(r == 0);
77*7c3d14c8STreehugger Robot }
78*7c3d14c8STreehugger Robot 
test5(char * array,char * endptr)79*7c3d14c8STreehugger Robot void test5(char *array, char *endptr) {
80*7c3d14c8STreehugger Robot   // Overflow if no digits are found.
81*7c3d14c8STreehugger Robot   array[0] = ' ';
82*7c3d14c8STreehugger Robot   array[1] = '+';
83*7c3d14c8STreehugger Robot   array[2] = '-';
84*7c3d14c8STreehugger Robot   long r = strtol(array, NULL, 0);
85*7c3d14c8STreehugger Robot   assert(r == 0);
86*7c3d14c8STreehugger Robot }
87*7c3d14c8STreehugger Robot 
test6(char * array,char * endptr)88*7c3d14c8STreehugger Robot void test6(char *array, char *endptr) {
89*7c3d14c8STreehugger Robot   // Overflow if no digits are found.
90*7c3d14c8STreehugger Robot   array[0] = ' ';
91*7c3d14c8STreehugger Robot   array[1] = array[2] = 'z';
92*7c3d14c8STreehugger Robot   long r = strtol(array, &endptr, 0);
93*7c3d14c8STreehugger Robot   assert(array == endptr);
94*7c3d14c8STreehugger Robot   assert(r == 0);
95*7c3d14c8STreehugger Robot }
96*7c3d14c8STreehugger Robot 
test7(char * array,char * endptr)97*7c3d14c8STreehugger Robot void test7(char *array, char *endptr) {
98*7c3d14c8STreehugger Robot   // Overflow if no digits are found.
99*7c3d14c8STreehugger Robot   array[2] = 'z';
100*7c3d14c8STreehugger Robot   long r = strtol(array + 2, NULL, 0);
101*7c3d14c8STreehugger Robot   assert(r == 0);
102*7c3d14c8STreehugger Robot }
103*7c3d14c8STreehugger Robot 
main(int argc,char ** argv)104*7c3d14c8STreehugger Robot int main(int argc, char **argv) {
105*7c3d14c8STreehugger Robot   char *array0 = (char*)malloc(11);
106*7c3d14c8STreehugger Robot   char* array = array0 + 8;
107*7c3d14c8STreehugger Robot   char *endptr = NULL;
108*7c3d14c8STreehugger Robot   array[0] = '1';
109*7c3d14c8STreehugger Robot   array[1] = '2';
110*7c3d14c8STreehugger Robot   array[2] = '3';
111*7c3d14c8STreehugger Robot   if (argc != 2) return 1;
112*7c3d14c8STreehugger Robot   if (!strcmp(argv[1], "test1")) test1(array, endptr);
113*7c3d14c8STreehugger Robot   // CHECK1: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
114*7c3d14c8STreehugger Robot   // CHECK1: READ of size 4
115*7c3d14c8STreehugger Robot   if (!strcmp(argv[1], "test2")) test2(array, endptr);
116*7c3d14c8STreehugger Robot   // CHECK2: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
117*7c3d14c8STreehugger Robot   // CHECK2: READ of size 4
118*7c3d14c8STreehugger Robot   if (!strcmp(argv[1], "test3")) test3(array0, endptr);
119*7c3d14c8STreehugger Robot   // CHECK3: {{.*ERROR: AddressSanitizer: use-after-poison on address}}
120*7c3d14c8STreehugger Robot   // CHECK3: READ of size 1
121*7c3d14c8STreehugger Robot   if (!strcmp(argv[1], "test4")) test4(array, endptr);
122*7c3d14c8STreehugger Robot   // CHECK4: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
123*7c3d14c8STreehugger Robot   // CHECK4: READ of size 1
124*7c3d14c8STreehugger Robot   if (!strcmp(argv[1], "test5")) test5(array, endptr);
125*7c3d14c8STreehugger Robot   // CHECK5: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
126*7c3d14c8STreehugger Robot   // CHECK5: READ of size 4
127*7c3d14c8STreehugger Robot   if (!strcmp(argv[1], "test6")) test6(array, endptr);
128*7c3d14c8STreehugger Robot   // CHECK6: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
129*7c3d14c8STreehugger Robot   // CHECK6: READ of size 4
130*7c3d14c8STreehugger Robot   if (!strcmp(argv[1], "test7")) test7(array, endptr);
131*7c3d14c8STreehugger Robot   // CHECK7: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}}
132*7c3d14c8STreehugger Robot   // CHECK7: READ of size 2
133*7c3d14c8STreehugger Robot   free(array0);
134*7c3d14c8STreehugger Robot   return 0;
135*7c3d14c8STreehugger Robot }
136