mirror of
https://github.com/github/codeql.git
synced 2025-12-21 19:26:31 +01:00
The IR false positives are due to the same path length limit as the AST false positives on the same line.
80 lines
1.6 KiB
C++
80 lines
1.6 KiB
C++
namespace Complex
|
|
{
|
|
class Foo
|
|
{
|
|
int a_;
|
|
int b_;
|
|
|
|
public:
|
|
int a() { return a_; }
|
|
int b() { return b_; }
|
|
void setA(int a) { a_ = a; }
|
|
void setB(int b) { b_ = b; }
|
|
|
|
Foo(int a, int b) : a_(a), b_(b){};
|
|
};
|
|
|
|
class Bar
|
|
{
|
|
public:
|
|
Foo f;
|
|
|
|
Bar() : f(0, 0) {}
|
|
};
|
|
|
|
class Outer
|
|
{
|
|
public:
|
|
Bar inner;
|
|
};
|
|
|
|
int user_input()
|
|
{
|
|
return 42;
|
|
}
|
|
|
|
void sink(int x)
|
|
{
|
|
}
|
|
|
|
void bar(Outer &b)
|
|
{
|
|
// The library correctly finds that the four `user_input` sources can make it
|
|
// to the `sink` calls, but it also finds some source/sink combinations that
|
|
// are impossible. Those false positives here are a consequence of how the
|
|
// shared data flow library overapproximates field flow. The library only
|
|
// tracks the final two fields (`f` and `inner`) and the length (3) of the field
|
|
// access path, and then it tracks that both `a_` and `b_` have followed `f.inner`
|
|
// in _some_ access path somewhere in the search. That makes the library conclude
|
|
// that there could be flow to `b.inner.f.a_` even when the flow was actually to
|
|
// `b.inner.f.b_`.
|
|
sink(b.inner.f.a()); // $ast=62:19 $f+:ast=63:19 $ast=64:19 $f+:ast=65:19 $ir=62:19 $f+:ir=63:19 $ir=64:19 $f+:ir=65:19
|
|
sink(b.inner.f.b()); // $f+:ast=62:19 $ast=63:19 $f+:ast=64:19 $ast=65:19 $f+:ir=62:19 $ir=63:19 $f+:ir=64:19 $ir=65:19
|
|
}
|
|
|
|
void foo()
|
|
{
|
|
Outer b1;
|
|
Outer b2;
|
|
Outer b3;
|
|
Outer b4;
|
|
|
|
b1.inner.f.setA(user_input());
|
|
b2.inner.f.setB(user_input());
|
|
b3.inner.f.setA(user_input());
|
|
b3.inner.f.setB(user_input());
|
|
|
|
// Only a() should alert
|
|
bar(b1);
|
|
|
|
// Only b() should alert
|
|
bar(b2);
|
|
|
|
// Both a() and b() should alert
|
|
bar(b3);
|
|
|
|
// Nothing should alert
|
|
bar(b4);
|
|
}
|
|
}; // namespace Complex
|