mirror of
https://github.com/github/codeql.git
synced 2026-03-06 15:49:08 +01:00
C++: Annotation field flow tests with [IR] and [AST]
This commit is contained in:
@@ -40,21 +40,21 @@ public:
|
||||
cc.insert(nullptr);
|
||||
ct.insert(new C());
|
||||
sink(&cc); // no flow
|
||||
sink(&ct); // flow
|
||||
sink(&ct); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
void f1()
|
||||
{
|
||||
C *c = new C();
|
||||
B *b = B::make(c);
|
||||
sink(b->c); // flow
|
||||
sink(b->c); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
void f2()
|
||||
{
|
||||
B *b = new B();
|
||||
b->set(new C1());
|
||||
sink(b->get()); // flow
|
||||
sink((new B(new C()))->get()); // flow
|
||||
sink(b->get()); // flow [NOT DETECTED by IR]
|
||||
sink((new B(new C()))->get()); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
void f3()
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
B *b2;
|
||||
b2 = setOnB(b1, new C2());
|
||||
sink(b1->c); // no flow
|
||||
sink(b2->c); // flow
|
||||
sink(b2->c); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
void f4()
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
B *b2;
|
||||
b2 = setOnBWrap(b1, new C2());
|
||||
sink(b1->c); // no flow
|
||||
sink(b2->c); // flow
|
||||
sink(b2->c); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
B *setOnBWrap(B *b1, C *c)
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
{
|
||||
if (C1 *c1 = dynamic_cast<C1 *>(c))
|
||||
{
|
||||
sink(c1->a); // flow
|
||||
sink(c1->a); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
C *cc;
|
||||
if (C2 *c2 = dynamic_cast<C2 *>(c))
|
||||
@@ -117,7 +117,7 @@ public:
|
||||
}
|
||||
if (C1 *c1 = dynamic_cast<C1 *>(cc))
|
||||
{
|
||||
sink(c1->a); // no flow, stopped by cast to C2 [FALSE POSITIVE]
|
||||
sink(c1->a); // no flow, stopped by cast to C2 [FALSE POSITIVE in AST]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ public:
|
||||
{
|
||||
B *b = new B();
|
||||
f7(b);
|
||||
sink(b->c); // flow
|
||||
sink(b->c); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
class D
|
||||
@@ -149,8 +149,8 @@ public:
|
||||
{
|
||||
B *b = new B();
|
||||
D *d = new D(b, r());
|
||||
sink(d->b); // flow x2
|
||||
sink(d->b->c); // flow
|
||||
sink(d->b); // flow x2 [NOT DETECTED by IR]
|
||||
sink(d->b->c); // flow [NOT DETECTED by IR]
|
||||
sink(b->c); // flow
|
||||
}
|
||||
|
||||
@@ -162,11 +162,11 @@ public:
|
||||
MyList *l3 = new MyList(nullptr, l2);
|
||||
sink(l3->head); // no flow, b is nested beneath at least one ->next
|
||||
sink(l3->next->head); // no flow
|
||||
sink(l3->next->next->head); // flow
|
||||
sink(l3->next->next->head); // flow [NOT DETECTED by IR]
|
||||
sink(l3->next->next->next->head); // no flow
|
||||
for (MyList *l = l3; l != nullptr; l = l->next)
|
||||
{
|
||||
sink(l->head); // flow
|
||||
sink(l->head); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ class B
|
||||
Elem *e = new Elem();
|
||||
Box1 *b1 = new Box1(e, nullptr);
|
||||
Box2 *b2 = new Box2(b1);
|
||||
sink(b2->box1->elem1); // flow
|
||||
sink(b2->box1->elem1); // flow [NOT DETECTED by IR]
|
||||
sink(b2->box1->elem2); // no flow
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class B
|
||||
Box1 *b1 = new B::Box1(nullptr, e);
|
||||
Box2 *b2 = new Box2(b1);
|
||||
sink(b2->box1->elem1); // no flow
|
||||
sink(b2->box1->elem2); // flow
|
||||
sink(b2->box1->elem2); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
static void sink(void *o) {}
|
||||
|
||||
@@ -26,9 +26,9 @@ public:
|
||||
|
||||
void func()
|
||||
{
|
||||
sink(s1); // flow
|
||||
sink(s1); // flow [NOT DETECTED by IR]
|
||||
sink(s2); // flow [NOT DETECTED]
|
||||
sink(s3); // flow
|
||||
sink(s3); // flow [NOT DETECTED by IR]
|
||||
sink(s4); // flow [NOT DETECTED]
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
};
|
||||
|
||||
static void sinkWrap(Box2* b2) {
|
||||
sink(b2->getBox1()->getElem());
|
||||
sink(b2->getBox1()->getElem()); // flow from f1, f2, f3, f9 [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
Box2* boxfield;
|
||||
@@ -61,6 +61,6 @@ public:
|
||||
|
||||
private:
|
||||
void f5b() {
|
||||
sink(boxfield->box->elem);
|
||||
sink(boxfield->box->elem); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@ void sink(char *b);
|
||||
|
||||
void handlePacket(packet *p)
|
||||
{
|
||||
sink(p->data.buffer);
|
||||
sink(p->data.buffer); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
void f(buf* b)
|
||||
@@ -28,7 +28,7 @@ void f(buf* b)
|
||||
argument_source(raw);
|
||||
argument_source(b->buffer);
|
||||
argument_source(p.data.buffer);
|
||||
sink(raw);
|
||||
sink(b->buffer);
|
||||
sink(raw); // flow [NOT DETECTED by IR]
|
||||
sink(b->buffer); // flow [NOT DETECTED by IR]
|
||||
handlePacket(&p);
|
||||
}
|
||||
@@ -35,12 +35,12 @@ void assignAfterAlias() {
|
||||
S s1 = { 0, 0 };
|
||||
S &ref1 = s1;
|
||||
ref1.m1 = user_input();
|
||||
sink(s1.m1); // flow [FALSE NEGATIVE]
|
||||
sink(s1.m1); // flow [NOT DETECTED by AST]
|
||||
|
||||
S s2 = { 0, 0 };
|
||||
S &ref2 = s2;
|
||||
s2.m1 = user_input();
|
||||
sink(ref2.m1); // flow [FALSE NEGATIVE]
|
||||
sink(ref2.m1); // flow [NOT DETECTED by AST]
|
||||
}
|
||||
|
||||
void assignAfterCopy() {
|
||||
@@ -77,14 +77,14 @@ void pointerIntermediate() {
|
||||
Wrapper w = { { 0, 0 } };
|
||||
S *s = &w.s;
|
||||
s->m1 = user_input();
|
||||
sink(w.s.m1); // flow [FALSE NEGATIVE]
|
||||
sink(w.s.m1); // flow [NOT DETECTED by AST]
|
||||
}
|
||||
|
||||
void referenceIntermediate() {
|
||||
Wrapper w = { { 0, 0 } };
|
||||
S &s = w.s;
|
||||
s.m1 = user_input();
|
||||
sink(w.s.m1); // flow [FALSE NEGATIVE]
|
||||
sink(w.s.m1); // flow [NOT DETECTED by AST]
|
||||
}
|
||||
|
||||
void nestedAssign() {
|
||||
|
||||
@@ -48,25 +48,25 @@ struct S {
|
||||
void test_setDirectly() {
|
||||
S s;
|
||||
s.setDirectly(user_input());
|
||||
sink(s.getDirectly()); // flow
|
||||
sink(s.getDirectly()); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
void test_setIndirectly() {
|
||||
S s;
|
||||
s.setIndirectly(user_input());
|
||||
sink(s.getIndirectly()); // flow
|
||||
sink(s.getIndirectly()); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
void test_setThroughNonMember() {
|
||||
S s;
|
||||
s.setThroughNonMember(user_input());
|
||||
sink(s.getThroughNonMember()); // flow
|
||||
sink(s.getThroughNonMember()); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
void test_nonMemberSetA() {
|
||||
S s;
|
||||
nonMemberSetA(&s, user_input());
|
||||
sink(nonMemberGetA(&s)); // flow
|
||||
sink(nonMemberGetA(&s)); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
////////////////////
|
||||
@@ -127,7 +127,7 @@ void test_outer_with_ref(Outer *pouter) {
|
||||
taint_inner_a_ref(*pouter->inner_ptr);
|
||||
taint_a_ref(pouter->a);
|
||||
|
||||
sink(outer.inner_nested.a); // flow
|
||||
sink(outer.inner_nested.a); // flow [IR]
|
||||
sink(outer.inner_ptr->a); // flow [NOT DETECTED by IR]
|
||||
sink(outer.a); // flow [NOT DETECTED by IR]
|
||||
|
||||
|
||||
@@ -41,8 +41,8 @@ void bar(Bar &b)
|
||||
// then it tracks that both `a_` and `b_` have followed `f` in _some_ access
|
||||
// path somewhere in the search. That makes the library conclude that there
|
||||
// could be flow to `b.f.a_` even when the flow was actually to `b.f.b_`.
|
||||
sink(b.f.a()); // flow [FALSE POSITIVE through `b2.f.setB` and `b3.f.setB`]
|
||||
sink(b.f.b()); // flow [FALSE POSITIVE through `b1.f.setA` and `b3.f.setA`]
|
||||
sink(b.f.a()); // flow [FALSE POSITIVE through `b2.f.setB` and `b3.f.setB` in AST, NOT DETECTED by IR]
|
||||
sink(b.f.b()); // flow [FALSE POSITIVE through `b1.f.setA` (AST) and `b3.f.setA` in AST, NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
void foo()
|
||||
|
||||
@@ -25,8 +25,8 @@ public:
|
||||
|
||||
void bar(Foo &f)
|
||||
{
|
||||
sink(f.a()); // flow (through `f` and `h`)
|
||||
sink(f.b()); // flow (through `g` and `h`)
|
||||
sink(f.a()); // flow (through `f` and `h`) [NOT DETECTED by IR]
|
||||
sink(f.b()); // flow (through `g` and `h`) [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
void foo()
|
||||
|
||||
@@ -64,7 +64,7 @@ void single_field_test()
|
||||
A a;
|
||||
a.i = user_input();
|
||||
A a2 = a;
|
||||
sink(a2.i);
|
||||
sink(a2.i); // flow
|
||||
}
|
||||
|
||||
struct C {
|
||||
@@ -81,7 +81,7 @@ struct C2
|
||||
|
||||
void m() {
|
||||
f2.f1 = user_input();
|
||||
sink(getf2f1()); // flow
|
||||
sink(getf2f1()); // flow [NOT DETECTED by IR]
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -12,32 +12,32 @@ struct Outer {
|
||||
};
|
||||
|
||||
void absink(struct AB *ab) {
|
||||
sink(ab->a); // flow (three sources)
|
||||
sink(ab->a); // flow from (1), (2), (3) [NOT DETECTED by IR]
|
||||
sink(ab->b); // no flow
|
||||
}
|
||||
|
||||
int struct_init(void) {
|
||||
struct AB ab = { user_input(), 0 };
|
||||
struct AB ab = { user_input(), 0 }; // (1)
|
||||
|
||||
sink(ab.a); // flow
|
||||
sink(ab.b); // no flow
|
||||
absink(&ab);
|
||||
|
||||
struct Outer outer = {
|
||||
{ user_input(), 0 },
|
||||
{ user_input(), 0 }, // (2)
|
||||
&ab,
|
||||
};
|
||||
|
||||
sink(outer.nestedAB.a); // flow
|
||||
sink(outer.nestedAB.b); // no flow
|
||||
sink(outer.pointerAB->a); // flow
|
||||
sink(outer.pointerAB->a); // flow [NOT DETECTED by IR]
|
||||
sink(outer.pointerAB->b); // no flow
|
||||
|
||||
absink(&outer.nestedAB);
|
||||
}
|
||||
|
||||
int struct_init2(void) {
|
||||
struct AB ab = { user_input(), 0 };
|
||||
struct AB ab = { user_input(), 0 }; // (3)
|
||||
struct Outer outer = {
|
||||
{ user_input(), 0 },
|
||||
&ab,
|
||||
|
||||
Reference in New Issue
Block a user