Add extra test cases

This commit is contained in:
Pavel Avgustinov
2019-07-18 11:30:10 +01:00
committed by Jonas Jensen
parent 835e495e7c
commit 79d75d7d18
5 changed files with 179 additions and 3 deletions

View File

@@ -0,0 +1,64 @@
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) {}
};
int user_input()
{
return 42;
}
void sink(int x)
{
}
void bar(Bar &b)
{
sink(b.f.a());
sink(b.f.b());
}
void foo()
{
Bar b1;
Bar b2;
Bar b3;
Bar b4;
b1.f.setA(user_input());
b2.f.setB(user_input());
b3.f.setA(user_input());
b3.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

View File

@@ -0,0 +1,51 @@
namespace Constructors
{
int user_input()
{
return 42;
}
void sink(int x)
{
}
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){};
};
void bar(Foo &f)
{
sink(f.a());
sink(f.b());
}
void foo()
{
Foo f(user_input(), 0);
Foo g(0, user_input());
Foo h(user_input(), user_input());
Foo i(0, 0);
// Only a() should alert
bar(f);
// Only b() should alert
bar(g);
// Both a() and b() should alert
bar(h);
// Nothing should alert
bar(i);
}
}; // namespace Constructors

View File

@@ -1,5 +1,5 @@
edges
| A.cpp:41:10:41:16 | new [void] | A.cpp:43:10:43:12 | & ... |
| A.cpp:41:15:41:21 | new [void] | A.cpp:43:10:43:12 | & ... |
| A.cpp:47:12:47:18 | new [void] | A.cpp:48:20:48:20 | c [void] |
| A.cpp:48:12:48:18 | call to make [c, ... (1)] | A.cpp:49:10:49:10 | b [c, ... (1)] |
| A.cpp:48:20:48:20 | c [void] | A.cpp:48:12:48:18 | call to make [c, ... (1)] |
@@ -90,7 +90,7 @@ edges
| C.cpp:27:8:27:11 | `this` parameter in func [s3, ... (1)] | file://:0:0:0:0 | this [s3, ... (1)] |
| file://:0:0:0:0 | this [s3, ... (1)] | C.cpp:31:10:31:11 | s3 |
#select
| A.cpp:43:10:43:12 | & ... | A.cpp:41:10:41:16 | new [void] | A.cpp:43:10:43:12 | & ... | & ... flows from $@ | A.cpp:41:10:41:16 | new [void] | new [void] |
| A.cpp:43:10:43:12 | & ... | A.cpp:41:15:41:21 | new [void] | A.cpp:43:10:43:12 | & ... | & ... flows from $@ | A.cpp:41:15:41:21 | new [void] | new [void] |
| A.cpp:49:13:49:13 | c | A.cpp:47:12:47:18 | new [void] | A.cpp:49:13:49:13 | c | c flows from $@ | A.cpp:47:12:47:18 | new [void] | new [void] |
| A.cpp:56:13:56:15 | call to get | A.cpp:55:12:55:19 | new [void] | A.cpp:56:13:56:15 | call to get | call to get flows from $@ | A.cpp:55:12:55:19 | new [void] | new [void] |
| A.cpp:57:28:57:30 | call to get | A.cpp:57:17:57:23 | new [void] | A.cpp:57:28:57:30 | call to get | call to get flows from $@ | A.cpp:57:17:57:23 | new [void] | new [void] |

View File

@@ -6,10 +6,15 @@ import semmle.code.cpp.dataflow.DataFlow
import DataFlow::PathGraph
import DataFlow
import cpp
class Conf extends Configuration {
Conf() { this = "FieldFlowConf" }
override predicate isSource(Node src) { src.asExpr() instanceof NewExpr }
override predicate isSource(Node src) {
src.asExpr() instanceof NewExpr
or
src.asExpr().(Call).getTarget().hasName("user_input")
}
override predicate isSink(Node sink) {
exists(Call c |

View File

@@ -0,0 +1,56 @@
namespace Simple
{
int user_input()
{
return 42;
}
void sink(int x)
{
}
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){};
};
void bar(Foo &f)
{
sink(f.a());
sink(f.b());
}
void foo()
{
Foo f(0, 0);
Foo g(0, 0);
Foo h(0, 0);
Foo i(0, 0);
f.setA(user_input());
g.setB(user_input());
h.setA(user_input());
h.setB(user_input());
// Only a() should alert
bar(f);
// Only b() should alert
bar(g);
// Both a() and b() should alert
bar(h);
// Nothing should alert
bar(i);
}
} // namespace Simple