1 /* PR middle-end/91582 - missing heap overflow detection for strcpy
2    { dg-do compile }
3    { dg-options "-O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0" } */
4 
5 #include "../../gcc.dg/range.h"
6 
7 #define INT_MAX     __INT_MAX__
8 #define INT_MIN     (-INT_MAX - 1)
9 
10 extern "C" char* strcpy (char*, const char*);
11 
12 void sink (void*);
13 
14 #define S36 "0123456789abcdefghijklmnopqrstuvwxyz"
15 #define S(N) (S36 + sizeof S36 - N - 1)
16 
17 #define T(src, alloc) do {			\
18     const char *s = src;			\
19     char *d = (char*)alloc;			\
20     strcpy (d, s);				\
21     sink (d);					\
22   } while (0)
23 
24 
test_strcpy_new_char(size_t n)25 void test_strcpy_new_char (size_t n)
26 {
27   size_t r_0_1 = UR (0, 1);
28   size_t r_1_2 = UR (1, 2);
29   size_t r_2_3 = UR (2, 3);
30 
31   T (S (0), new char[r_0_1]);
32   T (S (1), new char[r_0_1]);       // { dg-warning "\\\[-Wstringop-overflow" }
33 
34   T (S (0), new char[r_1_2]);
35   T (S (1), new char[r_1_2]);
36   T (S (2), new char[r_1_2]);       // { dg-warning "\\\[-Wstringop-overflow" }
37 
38   T (S (0), new char[r_2_3]);
39   T (S (2), new char[r_2_3]);
40   T (S (3), new char[r_2_3]);       // { dg-warning "\\\[-Wstringop-overflow" }
41   T (S (9), new char[r_2_3]);       // { dg-warning "\\\[-Wstringop-overflow" }
42 
43   size_t r_2_smax = UR (2, SIZE_MAX);
44   T (S (0), new char[r_2_smax]);
45   T (S (1), new char[r_2_smax]);
46   T (S (2), new char[r_2_smax]);
47   T (S (3), new char[r_2_smax * 2]);
48   T (S (4), new char[r_2_smax * 2 + 1]);
49 
50   T (S (1), new char[n]);
51   T (S (2), new char[n + 1]);
52   T (S (9), new char[n * 2 + 1]);
53 
54   int r_imin_imax = SR (INT_MIN, INT_MAX);
55   T (S (1), new char[r_imin_imax]);
56   T (S (2), new char[r_imin_imax + 1]);
57   T (S (9), new char[r_imin_imax * 2 + 1]);
58 
59   int r_0_imax = SR (0, INT_MAX);
60   T (S (1), new char[r_0_imax]);
61   T (S (2), new char[r_0_imax + 1]);
62   T (S (9), new char[r_0_imax * 2 + 1]);
63 
64   int r_1_imax = SR (1, INT_MAX);
65   T (S (1), new char[r_1_imax]);
66   T (S (2), new char[r_1_imax + 1]);
67   T (S (9), new char[r_1_imax * 2 + 1]);
68 
69   ptrdiff_t r_dmin_dmax = SR (DIFF_MIN, DIFF_MAX);
70   T (S (1), new char[r_dmin_dmax]);
71   T (S (2), new char[r_dmin_dmax + 1]);
72   T (S (9), new char[r_dmin_dmax * 2 + 1]);
73 }
74 
75 
test_strcpy_new_char_array(size_t n)76 void test_strcpy_new_char_array (size_t n)
77 {
78   size_t r_0_1 = UR (0, 1);
79 
80   T (S (0), new char[r_0_1][1]);
81   T (S (1), new char[r_0_1][1]);    // { dg-warning "\\\[-Wstringop-overflow" }
82   T (S (1), new char[r_0_1][2]);
83   T (S (2), new char[r_0_1][2]);    // { dg-warning "\\\[-Wstringop-overflow" }
84 
85   size_t r_1_2 = UR (1, 2);
86   T (S (0), new char[r_1_2][0]);    // { dg-warning "\\\[-Wstringop-overflow" }
87   T (S (0), new char[r_1_2][1]);
88   T (S (1), new char[r_1_2][1]);
89   T (S (2), new char[r_1_2][1]);    // { dg-warning "\\\[-Wstringop-overflow" }
90 
91   T (S (0), new char[r_1_2][0]);    // { dg-warning "\\\[-Wstringop-overflow" }
92   T (S (0), new char[r_1_2][1]);
93   T (S (1), new char[r_1_2][2]);
94   T (S (3), new char[r_1_2][2]);
95   T (S (4), new char[r_1_2][2]);    // { dg-warning "\\\[-Wstringop-overflow" }
96 }
97 
98 
99 #ifdef __INT16_TYPE__
100 
101 // Hack around PR 92829.
102 #define XUR(min, max) \
103   (++idx, (vals[idx] < min || max < vals[idx] ? min : vals[idx]))
104 
105 typedef __INT16_TYPE__ int16_t;
106 
test_strcpy_new_int16_t(size_t n,const size_t vals[])107 void test_strcpy_new_int16_t (size_t n, const size_t vals[])
108 {
109   size_t idx = 0;
110 
111   size_t r_0_1 = XUR (0, 1);
112   size_t r_1_2 = XUR (1, 2);
113   size_t r_2_3 = XUR (2, 3);
114 
115   T (S (0), new int16_t[r_0_1]);
116   T (S (1), new int16_t[r_0_1]);
117   T (S (2), new int16_t[r_0_1]);      // { dg-warning "\\\[-Wstringop-overflow" }
118 
119   T (S (0), new int16_t[r_1_2]);
120   T (S (1), new int16_t[r_1_2]);
121   T (S (2), new int16_t[r_1_2]);
122   T (S (3), new int16_t[r_1_2]);
123   T (S (4), new int16_t[r_1_2]);      // { dg-warning "\\\[-Wstringop-overflow" }
124 
125   T (S (0), new int16_t[r_2_3]);
126   T (S (1), new int16_t[r_2_3]);
127   T (S (5), new int16_t[r_2_3]);
128   T (S (6), new int16_t[r_2_3]);      // { dg-warning "\\\[-Wstringop-overflow" }
129   T (S (9), new int16_t[r_2_3]);      // { dg-warning "\\\[-Wstringop-overflow" }
130 
131   size_t r_2_smax = XUR (2, SIZE_MAX);
132   T (S (0), new int16_t[r_2_smax]);
133   T (S (1), new int16_t[r_2_smax]);
134   T (S (2), new int16_t[r_2_smax]);
135   T (S (3), new int16_t[r_2_smax * 2]);
136   T (S (4), new int16_t[r_2_smax * 2 + 1]);
137 
138   T (S (1), new int16_t[n]);
139   T (S (2), new int16_t[n + 1]);
140   T (S (9), new int16_t[n * 2 + 1]);
141 
142   int r_imin_imax = SR (INT_MIN, INT_MAX);
143   T (S (1), new int16_t[r_imin_imax]);
144   T (S (2), new int16_t[r_imin_imax + 1]);
145   T (S (9), new int16_t[r_imin_imax * 2 + 1]);
146 
147   int r_0_imax = SR (0, INT_MAX);
148   T (S (1), new int16_t[r_0_imax]);
149   T (S (2), new int16_t[r_0_imax + 1]);
150   T (S (9), new int16_t[r_0_imax * 2 + 1]);
151 
152   int r_1_imax = SR (1, INT_MAX);
153   T (S (1), new int16_t[r_1_imax]);
154   T (S (2), new int16_t[r_1_imax + 1]);
155   T (S (9), new int16_t[r_1_imax * 2 + 1]);
156 
157   ptrdiff_t r_dmin_dmax = SR (DIFF_MIN, DIFF_MAX);
158   T (S (1), new int16_t[r_dmin_dmax]);
159   T (S (2), new int16_t[r_dmin_dmax + 1]);
160   T (S (9), new int16_t[r_dmin_dmax * 2 + 1]);
161 }
162 
163 #endif   // int16_t
164