Add tests exhibiting false positives in the dataflow library, where call context is not used to prune branches.

This commit is contained in:
Cornelius Riemenschneider
2019-09-24 13:34:55 +02:00
committed by Anders Schack-Mulligen
parent 3f45d8614b
commit dba93b30e7
4 changed files with 223 additions and 0 deletions

View File

@@ -0,0 +1,104 @@
public class A {
public static void sink(Object o) {
}
public void callSinkIfTrue(Object o, boolean cond) {
if (cond) {
sink(o);
}
}
public void callSinkIfFalse(Object o, boolean cond) {
if (!cond) {
sink(o);
}
}
public void callSinkFromLoop(Object o, boolean cond) {
while (cond) {
sink(o);
}
}
public void localCallSensitivity(Object o, boolean c) {
Object o1 = o;
Object o2 = null;
if (c) {
Object tmp = o1;
o2 = 1 == 1 ? (tmp) : (tmp);
}
Object o3 = o2;
sink(o3);
}
public void f1() {
// should not exhibit flow
callSinkIfTrue(new Integer(1), false);
callSinkIfFalse(new Integer(2), true);
callSinkFromLoop(new Integer(3), false);
localCallSensitivity(new Integer(4), false);
// should exhibit flow
callSinkIfTrue(new Integer(1), true);
callSinkIfFalse(new Integer(2), false);
callSinkFromLoop(new Integer(3), true);
localCallSensitivity(new Integer(4), true);
}
public void f2() {
boolean t = true;
boolean f = false;
// should not exhibit flow
callSinkIfTrue(new Integer(4), f);
callSinkIfFalse(new Integer(5), t);
callSinkFromLoop(new Integer(6), f);
localCallSensitivity(new Integer(4), f);
// should exhibit flow
callSinkIfTrue(new Integer(4), t);
callSinkIfFalse(new Integer(5), f);
callSinkFromLoop(new Integer(6), t);
localCallSensitivity(new Integer(4), t);
}
public void f3(InterfaceA b) {
boolean t = true;
boolean f = false;
// should not exhibit flow
b.callSinkIfTrue(new Integer(4), f);
b.callSinkIfFalse(new Integer(5), t);
b.localCallSensitivity(new Integer(4), f);
// should exhibit flow
b.callSinkIfTrue(new Integer(4), t);
b.callSinkIfFalse(new Integer(5), f);
b.localCallSensitivity(new Integer(4), t);
}
class B implements InterfaceA {
@Override
public void callSinkIfTrue(Object o, boolean cond) {
if (cond) {
sink(o);
}
}
@Override
public void callSinkIfFalse(Object o, boolean cond) {
if (!cond) {
sink(o);
}
}
@Override
public void localCallSensitivity(Object o, boolean c) {
Object o1 = o;
Object o2 = null;
if (c) {
Object tmp = o1;
o2 = 1 == 1 ? (tmp) : (tmp);
}
Object o3 = o2;
sink(o3);
}
}
}

View File

@@ -0,0 +1,5 @@
public interface InterfaceA {
public void callSinkIfTrue(Object o, boolean cond);
public void callSinkIfFalse(Object o, boolean cond);
public void localCallSensitivity(Object o, boolean c);
}

View File

@@ -0,0 +1,90 @@
edges
| A.java:6:29:6:36 | o [ : Number] | A.java:8:9:8:9 | o |
| A.java:12:30:12:37 | o [ : Number] | A.java:14:9:14:9 | o |
| A.java:18:31:18:38 | o [ : Number] | A.java:20:9:20:9 | o |
| A.java:24:35:24:42 | o [ : Number] | A.java:32:8:32:9 | o3 |
| A.java:37:18:37:31 | new Integer(...) [ : Number] | A.java:6:29:6:36 | o [ : Number] |
| A.java:38:19:38:32 | new Integer(...) [ : Number] | A.java:12:30:12:37 | o [ : Number] |
| A.java:39:20:39:33 | new Integer(...) [ : Number] | A.java:18:31:18:38 | o [ : Number] |
| A.java:40:24:40:37 | new Integer(...) [ : Number] | A.java:24:35:24:42 | o [ : Number] |
| A.java:42:18:42:31 | new Integer(...) [ : Number] | A.java:6:29:6:36 | o [ : Number] |
| A.java:43:19:43:32 | new Integer(...) [ : Number] | A.java:12:30:12:37 | o [ : Number] |
| A.java:44:20:44:33 | new Integer(...) [ : Number] | A.java:18:31:18:38 | o [ : Number] |
| A.java:45:24:45:37 | new Integer(...) [ : Number] | A.java:24:35:24:42 | o [ : Number] |
| A.java:52:18:52:31 | new Integer(...) [ : Number] | A.java:6:29:6:36 | o [ : Number] |
| A.java:53:19:53:32 | new Integer(...) [ : Number] | A.java:12:30:12:37 | o [ : Number] |
| A.java:54:20:54:33 | new Integer(...) [ : Number] | A.java:18:31:18:38 | o [ : Number] |
| A.java:55:24:55:37 | new Integer(...) [ : Number] | A.java:24:35:24:42 | o [ : Number] |
| A.java:57:18:57:31 | new Integer(...) [ : Number] | A.java:6:29:6:36 | o [ : Number] |
| A.java:58:19:58:32 | new Integer(...) [ : Number] | A.java:12:30:12:37 | o [ : Number] |
| A.java:59:20:59:33 | new Integer(...) [ : Number] | A.java:18:31:18:38 | o [ : Number] |
| A.java:60:24:60:37 | new Integer(...) [ : Number] | A.java:24:35:24:42 | o [ : Number] |
| A.java:67:20:67:33 | new Integer(...) [ : Number] | A.java:78:30:78:37 | o [ : Number] |
| A.java:68:21:68:34 | new Integer(...) [ : Number] | A.java:85:31:85:38 | o [ : Number] |
| A.java:69:26:69:39 | new Integer(...) [ : Number] | A.java:92:36:92:43 | o [ : Number] |
| A.java:71:20:71:33 | new Integer(...) [ : Number] | A.java:78:30:78:37 | o [ : Number] |
| A.java:72:21:72:34 | new Integer(...) [ : Number] | A.java:85:31:85:38 | o [ : Number] |
| A.java:73:26:73:39 | new Integer(...) [ : Number] | A.java:92:36:92:43 | o [ : Number] |
| A.java:78:30:78:37 | o [ : Number] | A.java:80:10:80:10 | o |
| A.java:85:31:85:38 | o [ : Number] | A.java:87:10:87:10 | o |
| A.java:92:36:92:43 | o [ : Number] | A.java:100:9:100:10 | o3 |
nodes
| A.java:6:29:6:36 | o [ : Number] | semmle.label | o [ : Number] |
| A.java:8:9:8:9 | o | semmle.label | o |
| A.java:12:30:12:37 | o [ : Number] | semmle.label | o [ : Number] |
| A.java:14:9:14:9 | o | semmle.label | o |
| A.java:18:31:18:38 | o [ : Number] | semmle.label | o [ : Number] |
| A.java:20:9:20:9 | o | semmle.label | o |
| A.java:24:35:24:42 | o [ : Number] | semmle.label | o [ : Number] |
| A.java:32:8:32:9 | o3 | semmle.label | o3 |
| A.java:37:18:37:31 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:38:19:38:32 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:39:20:39:33 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:40:24:40:37 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:42:18:42:31 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:43:19:43:32 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:44:20:44:33 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:45:24:45:37 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:52:18:52:31 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:53:19:53:32 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:54:20:54:33 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:55:24:55:37 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:57:18:57:31 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:58:19:58:32 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:59:20:59:33 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:60:24:60:37 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:67:20:67:33 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:68:21:68:34 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:69:26:69:39 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:71:20:71:33 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:72:21:72:34 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:73:26:73:39 | new Integer(...) [ : Number] | semmle.label | new Integer(...) [ : Number] |
| A.java:78:30:78:37 | o [ : Number] | semmle.label | o [ : Number] |
| A.java:80:10:80:10 | o | semmle.label | o |
| A.java:85:31:85:38 | o [ : Number] | semmle.label | o [ : Number] |
| A.java:87:10:87:10 | o | semmle.label | o |
| A.java:92:36:92:43 | o [ : Number] | semmle.label | o [ : Number] |
| A.java:100:9:100:10 | o3 | semmle.label | o3 |
#select
| A.java:37:18:37:31 | new Integer(...) [ : Number] | A.java:37:18:37:31 | new Integer(...) [ : Number] | A.java:8:9:8:9 | o | $@ | A.java:8:9:8:9 | o | o |
| A.java:38:19:38:32 | new Integer(...) [ : Number] | A.java:38:19:38:32 | new Integer(...) [ : Number] | A.java:14:9:14:9 | o | $@ | A.java:14:9:14:9 | o | o |
| A.java:39:20:39:33 | new Integer(...) [ : Number] | A.java:39:20:39:33 | new Integer(...) [ : Number] | A.java:20:9:20:9 | o | $@ | A.java:20:9:20:9 | o | o |
| A.java:40:24:40:37 | new Integer(...) [ : Number] | A.java:40:24:40:37 | new Integer(...) [ : Number] | A.java:32:8:32:9 | o3 | $@ | A.java:32:8:32:9 | o3 | o3 |
| A.java:42:18:42:31 | new Integer(...) [ : Number] | A.java:42:18:42:31 | new Integer(...) [ : Number] | A.java:8:9:8:9 | o | $@ | A.java:8:9:8:9 | o | o |
| A.java:43:19:43:32 | new Integer(...) [ : Number] | A.java:43:19:43:32 | new Integer(...) [ : Number] | A.java:14:9:14:9 | o | $@ | A.java:14:9:14:9 | o | o |
| A.java:44:20:44:33 | new Integer(...) [ : Number] | A.java:44:20:44:33 | new Integer(...) [ : Number] | A.java:20:9:20:9 | o | $@ | A.java:20:9:20:9 | o | o |
| A.java:45:24:45:37 | new Integer(...) [ : Number] | A.java:45:24:45:37 | new Integer(...) [ : Number] | A.java:32:8:32:9 | o3 | $@ | A.java:32:8:32:9 | o3 | o3 |
| A.java:52:18:52:31 | new Integer(...) [ : Number] | A.java:52:18:52:31 | new Integer(...) [ : Number] | A.java:8:9:8:9 | o | $@ | A.java:8:9:8:9 | o | o |
| A.java:53:19:53:32 | new Integer(...) [ : Number] | A.java:53:19:53:32 | new Integer(...) [ : Number] | A.java:14:9:14:9 | o | $@ | A.java:14:9:14:9 | o | o |
| A.java:54:20:54:33 | new Integer(...) [ : Number] | A.java:54:20:54:33 | new Integer(...) [ : Number] | A.java:20:9:20:9 | o | $@ | A.java:20:9:20:9 | o | o |
| A.java:55:24:55:37 | new Integer(...) [ : Number] | A.java:55:24:55:37 | new Integer(...) [ : Number] | A.java:32:8:32:9 | o3 | $@ | A.java:32:8:32:9 | o3 | o3 |
| A.java:57:18:57:31 | new Integer(...) [ : Number] | A.java:57:18:57:31 | new Integer(...) [ : Number] | A.java:8:9:8:9 | o | $@ | A.java:8:9:8:9 | o | o |
| A.java:58:19:58:32 | new Integer(...) [ : Number] | A.java:58:19:58:32 | new Integer(...) [ : Number] | A.java:14:9:14:9 | o | $@ | A.java:14:9:14:9 | o | o |
| A.java:59:20:59:33 | new Integer(...) [ : Number] | A.java:59:20:59:33 | new Integer(...) [ : Number] | A.java:20:9:20:9 | o | $@ | A.java:20:9:20:9 | o | o |
| A.java:60:24:60:37 | new Integer(...) [ : Number] | A.java:60:24:60:37 | new Integer(...) [ : Number] | A.java:32:8:32:9 | o3 | $@ | A.java:32:8:32:9 | o3 | o3 |
| A.java:67:20:67:33 | new Integer(...) [ : Number] | A.java:67:20:67:33 | new Integer(...) [ : Number] | A.java:80:10:80:10 | o | $@ | A.java:80:10:80:10 | o | o |
| A.java:68:21:68:34 | new Integer(...) [ : Number] | A.java:68:21:68:34 | new Integer(...) [ : Number] | A.java:87:10:87:10 | o | $@ | A.java:87:10:87:10 | o | o |
| A.java:69:26:69:39 | new Integer(...) [ : Number] | A.java:69:26:69:39 | new Integer(...) [ : Number] | A.java:100:9:100:10 | o3 | $@ | A.java:100:9:100:10 | o3 | o3 |
| A.java:71:20:71:33 | new Integer(...) [ : Number] | A.java:71:20:71:33 | new Integer(...) [ : Number] | A.java:80:10:80:10 | o | $@ | A.java:80:10:80:10 | o | o |
| A.java:72:21:72:34 | new Integer(...) [ : Number] | A.java:72:21:72:34 | new Integer(...) [ : Number] | A.java:87:10:87:10 | o | $@ | A.java:87:10:87:10 | o | o |
| A.java:73:26:73:39 | new Integer(...) [ : Number] | A.java:73:26:73:39 | new Integer(...) [ : Number] | A.java:100:9:100:10 | o3 | $@ | A.java:100:9:100:10 | o3 | o3 |

View File

@@ -0,0 +1,24 @@
/**
* @kind path-problem
*/
import java
import semmle.code.java.dataflow.DataFlow
import DataFlow::PathGraph
class Conf extends DataFlow::Configuration {
Conf() { this = "CallSensitiveFlowConf" }
override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof ClassInstanceExpr }
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
ma.getMethod().hasName("sink") and
ma.getAnArgument() = sink.asExpr()
)
}
}
from DataFlow::PathNode source, DataFlow::PathNode sink, Conf conf
where conf.hasFlowPath(source, sink)
select source, source, sink, "$@", sink, sink.toString()