Files
codeql/cpp/ql/test/query-tests/Likely Bugs/Memory Management/UsingExpiredStackAddress/test.cpp

184 lines
2.9 KiB
C++

struct S100 {
int i;
int* p;
};
static struct S100 s101;
void escape1() {
int x;
s101.p = &x;
}
int simple_field_bad() {
escape1();
return *s101.p; // BAD
}
int simple_field_good() {
escape1();
return s101.i; // GOOD
}
int deref_p() {
return *s101.p;
}
int field_indirect_bad() {
escape1();
return deref_p(); // BAD [NOT DETECTED]
}
int deref_i() {
return s101.i;
}
int field_indirect_good() {
escape1();
return deref_i(); // GOOD
}
void store_argument(int *p) {
s101.p = p;
}
int store_argument_value() {
int x;
store_argument(&x);
return *s101.p; // GOOD
}
void store_address_of_argument(int x) {
s101.p = &x;
}
int store_argument_address() {
int x;
store_address_of_argument(x);
return *s101.p; // BAD
}
void address_escapes_through_pointer_arith() {
int x = 0;
int* p0 = &x;
int* p1 = p0 + 1;
int* p2 = p1 - 1;
int* p3 = 1 + p2;
p3++;
s101.p = p3;
}
int test_pointer_arith_bad() {
address_escapes_through_pointer_arith();
return *s101.p; // BAD
}
int test_pointer_arith_good_1() {
int x;
address_escapes_through_pointer_arith();
s101.p = &x;
return *s101.p; // GOOD [FALSE POSITIVE]
}
int test_pointer_arith_good_2(bool b) {
int x;
if(b) {
address_escapes_through_pointer_arith();
}
return *s101.p; // GOOD (we can't say for sure that this is a local address)
}
void field_address_escapes() {
S100 s;
s101.p = &s.i;
}
int test_field_address_escapes() {
field_address_escapes();
return s101.p[0]; // BAD
}
void escape_through_reference() {
int x = 0;
int& r0 = x;
int& r1 = r0;
r1++;
s101.p = &r1;
}
int test_escapes_through_reference() {
escape_through_reference();
return *s101.p; // BAD
}
struct S300 {
int a1[15];
int a2[14][15];
int a3[13][14][15];
int *p1;
int (*p2)[15];
int (*p3)[14][15];
int** pp;
};
S300 s1;
S300 s2;
S300 s3;
S300 s4;
S300 s5;
S300 s6;
void escape_through_arrays() {
int b1[15];
int b2[14][15];
int b3[13][14][15];
s1.p1 = b1;
s2.p1 = &b1[1];
s1.p2 = b2;
s2.p2 = &b2[1];
s3.p1 = b2[1];
s4.p1 = &b2[1][2];
s1.p3 = b3;
s2.p3 = &b3[1];
s3.p2 = b3[1];
s4.p2 = &b3[1][2];
s5.p1 = b3[1][2];
s6.p1 = &b3[1][2][3];
s1.pp[0] = b1;
s2.pp[0] = &b1[1];
s3.pp[0] = b2[1];
s4.pp[0] = &b2[1][2];
s5.pp[0] = b3[1][2];
s6.pp[0] = &b3[1][2][3];
}
void test_escape_through_arrays() {
escape_through_arrays();
int x1 = *s1.p1; // BAD
int x2 = *s2.p1; // BAD
int* x3 = s1.p2[1]; // BAD
int x4 = *s1.p2[1]; // BAD
int* x5 = *s2.p2; // BAD
int* x6 = s3.p1; // BAD
int x7 = *&s4.p1[1]; // BAD
int x8 = *s1.p3[1][2]; // BAD
int x9 = (*s2.p3[0])[0]; // BAD
int x10 = **s3.p2; // BAD
int x11 = **s4.p2; // BAD
int x12 = (*s4.p1); // BAD
int x13 = s5.p1[1]; // BAD
int* x14 = s1.pp[0]; // BAD
int x15 = *s2.pp[0]; // BAD
int x16 = *s3.pp[0]; // BAD
int x17 = **s4.pp; // BAD
int x18 = s5.pp[0][0]; // BAD
int x19 = (*s6.pp)[0]; // BAD
}