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
test1(int x)6 void test1(int x) {
7   int *buf = new int[100];
8   buf[100] = 1; // expected-warning{{Out of bound memory access}}
9 }
10 
test1_ok(int x)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
test1_ptr(int x)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 
test1_ptr_ok(int x)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
test1_ptr_arith(int x)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 
test1_ptr_arith_ok(int x)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 
test1_ptr_arith_bad(int x)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 
test1_ptr_arith_ok2(int x)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
test2(int x)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
test2_ptr(int x)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
test2_ptr_arith(int x)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
test2_multi(int x)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
test2_multi_b(int x)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
test2_multi_c(int x)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
test2_multi_2(int x)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
test2_multi_ok(int x)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
test_diff_types(int x)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
test_non_array(int x)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
test_dynamic_size(int s)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
test_dynamic_size2(unsigned m,unsigned n)153 void test_dynamic_size2(unsigned m,unsigned n){
154   unsigned *U = nullptr;
155   U = new unsigned[m + n + 1];
156 }
157