1 | // RUN: %clang_analyze_cc1 -std=c++11 -Wno-array-bounds -analyzer-checker=unix,core,alpha.security.ArrayBoundV2 -verify %s |
2 | |
3 | // Tests doing an out-of-bounds access after the end of an array using: |
4 | // - constant integer index |
5 | // - constant integer size for buffer |
6 | void test1(int x) { |
7 | int *buf = new int[100]; |
8 | buf[100] = 1; // expected-warning{{Out of bound memory access}} |
9 | } |
10 | |
11 | void test1_ok(int x) { |
12 | int *buf = new int[100]; |
13 | buf[99] = 1; // no-warning |
14 | } |
15 | |
16 | // Tests doing an out-of-bounds access after the end of an array using: |
17 | // - indirect pointer to buffer |
18 | // - constant integer index |
19 | // - constant integer size for buffer |
20 | void test1_ptr(int x) { |
21 | int *buf = new int[100]; |
22 | int *p = buf; |
23 | p[101] = 1; // expected-warning{{Out of bound memory access}} |
24 | } |
25 | |
26 | void test1_ptr_ok(int x) { |
27 | int *buf = new int[100]; |
28 | int *p = buf; |
29 | p[99] = 1; // no-warning |
30 | } |
31 | |
32 | // Tests doing an out-of-bounds access before the start of an array using: |
33 | // - indirect pointer to buffer, manipulated using simple pointer arithmetic |
34 | // - constant integer index |
35 | // - constant integer size for buffer |
36 | void test1_ptr_arith(int x) { |
37 | int *buf = new int[100]; |
38 | int *p = buf; |
39 | p = p + 100; |
40 | p[0] = 1; // expected-warning{{Out of bound memory access}} |
41 | } |
42 | |
43 | void test1_ptr_arith_ok(int x) { |
44 | int *buf = new int[100]; |
45 | int *p = buf; |
46 | p = p + 99; |
47 | p[0] = 1; // no-warning |
48 | } |
49 | |
50 | void test1_ptr_arith_bad(int x) { |
51 | int *buf = new int[100]; |
52 | int *p = buf; |
53 | p = p + 99; |
54 | p[1] = 1; // expected-warning{{Out of bound memory access}} |
55 | } |
56 | |
57 | void test1_ptr_arith_ok2(int x) { |
58 | int *buf = new int[100]; |
59 | int *p = buf; |
60 | p = p + 99; |
61 | p[-1] = 1; // no-warning |
62 | } |
63 | |
64 | // Tests doing an out-of-bounds access before the start of an array using: |
65 | // - constant integer index |
66 | // - constant integer size for buffer |
67 | void test2(int x) { |
68 | int *buf = new int[100]; |
69 | buf[-1] = 1; // expected-warning{{Out of bound memory access}} |
70 | } |
71 | |
72 | // Tests doing an out-of-bounds access before the start of an array using: |
73 | // - indirect pointer to buffer |
74 | // - constant integer index |
75 | // - constant integer size for buffer |
76 | void test2_ptr(int x) { |
77 | int *buf = new int[100]; |
78 | int *p = buf; |
79 | p[-1] = 1; // expected-warning{{Out of bound memory access}} |
80 | } |
81 | |
82 | // Tests doing an out-of-bounds access before the start of an array using: |
83 | // - indirect pointer to buffer, manipulated using simple pointer arithmetic |
84 | // - constant integer index |
85 | // - constant integer size for buffer |
86 | void test2_ptr_arith(int x) { |
87 | int *buf = new int[100]; |
88 | int *p = buf; |
89 | --p; |
90 | p[0] = 1; // expected-warning {{Out of bound memory access (accessed memory precedes memory block)}} |
91 | } |
92 | |
93 | // Tests under-indexing |
94 | // of a multi-dimensional array |
95 | void test2_multi(int x) { |
96 | auto buf = new int[100][100]; |
97 | buf[0][-1] = 1; // expected-warning{{Out of bound memory access}} |
98 | } |
99 | |
100 | // Tests under-indexing |
101 | // of a multi-dimensional array |
102 | void test2_multi_b(int x) { |
103 | auto buf = new int[100][100]; |
104 | buf[-1][0] = 1; // expected-warning{{Out of bound memory access}} |
105 | } |
106 | |
107 | // Tests over-indexing |
108 | // of a multi-dimensional array |
109 | void test2_multi_c(int x) { |
110 | auto buf = new int[100][100]; |
111 | buf[100][0] = 1; // expected-warning{{Out of bound memory access}} |
112 | } |
113 | |
114 | // Tests over-indexing |
115 | // of a multi-dimensional array |
116 | void test2_multi_2(int x) { |
117 | auto buf = new int[100][100]; |
118 | buf[99][100] = 1; // expected-warning{{Out of bound memory access}} |
119 | } |
120 | |
121 | // Tests normal access of |
122 | // a multi-dimensional array |
123 | void test2_multi_ok(int x) { |
124 | auto buf = new int[100][100]; |
125 | buf[0][0] = 1; // no-warning |
126 | } |
127 | |
128 | // Tests over-indexing using different types |
129 | // array |
130 | void test_diff_types(int x) { |
131 | int *buf = new int[10]; //10*sizeof(int) Bytes allocated |
132 | char *cptr = (char *)buf; |
133 | cptr[sizeof(int) * 9] = 1; // no-warning |
134 | cptr[sizeof(int) * 10] = 1; // expected-warning{{Out of bound memory access}} |
135 | } |
136 | |
137 | // Tests over-indexing |
138 | //if the allocated area is non-array |
139 | void test_non_array(int x) { |
140 | int *ip = new int; |
141 | ip[0] = 1; // no-warning |
142 | ip[1] = 2; // expected-warning{{Out of bound memory access}} |
143 | } |
144 | |
145 | //Tests over-indexing |
146 | //if the allocated area size is a runtime parameter |
147 | void test_dynamic_size(int s) { |
148 | int *buf = new int[s]; |
149 | buf[0] = 1; // no-warning |
150 | } |
151 | //Tests complex arithmetic |
152 | //in new expression |
153 | void test_dynamic_size2(unsigned m,unsigned n){ |
154 | unsigned *U = nullptr; |
155 | U = new unsigned[m + n + 1]; |
156 | } |
157 | |