Files
codeql/cpp/ql/test/library-tests/dataflow/fields/complex.cpp
Robert Marsh 65f4ef712e C++: accept false positive tests after merge
The IR false positives are due to the same path length limit as the AST
false positives on the same line.
2020-06-11 15:27:13 -07:00

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