Skip to content

Commit d4b18fe

Browse files
committed
[Java] JDK Collection lambda models
Adds support for data flow tracking through simple JDK collection functional APIs. - `Iterable::forEach` - `Iterator::forEachRemaining` - `Map::forEach` Replaces github#5871 Signed-off-by: Jonathan Leitschuh <[email protected]>
1 parent 233a334 commit d4b18fe

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ private class ContainerFlowSummaries extends SummaryModelCsv {
104104
"java.util;Map$Entry;true;setValue;;;Argument[0];MapValue of Argument[-1];value",
105105
"java.lang;Iterable;true;iterator;();;Element of Argument[-1];Element of ReturnValue;value",
106106
"java.lang;Iterable;true;spliterator;();;Element of Argument[-1];Element of ReturnValue;value",
107+
"java.lang;Iterable;true;forEach;(Consumer);;Element of Argument[-1];Parameter[0] of Argument[0];value",
107108
"java.util;Iterator;true;next;;;Element of Argument[-1];ReturnValue;value",
109+
"java.util;Iterator;true;forEachRemaining;(Consumer);;Element of Argument[-1];Parameter[0] of Argument[0];value",
108110
"java.util;ListIterator;true;previous;;;Element of Argument[-1];ReturnValue;value",
109111
"java.util;ListIterator;true;add;(Object);;Argument[0];Element of Argument[-1];value",
110112
"java.util;ListIterator;true;set;(Object);;Argument[0];Element of Argument[-1];value",
@@ -135,6 +137,8 @@ private class ContainerFlowSummaries extends SummaryModelCsv {
135137
"java.util;Map;true;merge;(Object,Object,BiFunction);;Argument[1];MapValue of Argument[-1];value",
136138
"java.util;Map;true;putAll;(Map);;MapKey of Argument[0];MapKey of Argument[-1];value",
137139
"java.util;Map;true;putAll;(Map);;MapValue of Argument[0];MapValue of Argument[-1];value",
140+
"java.util;Map;true;forEach;(BiConsumer);;MapKey of Argument[-1];Parameter[0] of Argument[0];value",
141+
"java.util;Map;true;forEach;(BiConsumer);;MapValue of Argument[-1];Parameter[1] of Argument[0];value",
138142
"java.util;Collection;true;parallelStream;();;Element of Argument[-1];Element of ReturnValue;value",
139143
"java.util;Collection;true;stream;();;Element of Argument[-1];Element of ReturnValue;value",
140144
"java.util;Collection;true;toArray;;;Element of Argument[-1];ArrayElement of ReturnValue;value",

java/ql/test/library-tests/dataflow/collections/Test.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,57 @@ public void run() {
2525
Iterator<String> it = m.values().iterator();
2626
String x5 = it.next();
2727
sink(x5); // Flow
28+
29+
it.forEachRemaining(x6 -> {
30+
sink(x6); // Flow
31+
});
32+
33+
m.forEach((x7_k, x8_v) -> {
34+
sink(x7_k); // No flow
35+
sink(x8_v); // Flow
36+
});
37+
38+
m.entrySet().forEach(entry -> {
39+
String x9 = entry.getKey();
40+
String x10 = entry.getValue();
41+
sink(x9); // No flow
42+
sink(x10); // Flow
43+
});
44+
}
45+
46+
public void run2() {
47+
HashMap<String, String> m = new HashMap<>();
48+
49+
m.put(tainted, tainted);
50+
51+
m.forEach((x11_k, x12_v) -> {
52+
sink(x11_k); // Flow
53+
sink(x12_v); // Flow
54+
});
55+
56+
m.entrySet().forEach(entry -> {
57+
String x13 = entry.getKey();
58+
String x14 = entry.getValue();
59+
sink(x13); // Flow
60+
sink(x14); // Flow
61+
});
62+
}
63+
64+
public void run3() {
65+
Set<String> s = new HashSet<>();
66+
String x15 = s.iterator().next();
67+
sink(x15); // No flow
68+
69+
s.forEach(x16 -> {
70+
sink(x16); // No flow
71+
});
72+
73+
s.add(tainted);
74+
String x17 = s.iterator().next();
75+
sink(x17); // Flow
76+
77+
s.forEach(x18 -> {
78+
sink(x18); // Flow
79+
});
2880
}
2981
}

java/ql/test/library-tests/dataflow/collections/flow.expected

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,12 @@
22
| Test.java:13:18:13:24 | tainted | Test.java:18:10:18:11 | x3 |
33
| Test.java:13:18:13:24 | tainted | Test.java:22:12:22:13 | x4 |
44
| Test.java:13:18:13:24 | tainted | Test.java:27:10:27:11 | x5 |
5+
| Test.java:13:18:13:24 | tainted | Test.java:30:12:30:13 | x6 |
6+
| Test.java:13:18:13:24 | tainted | Test.java:35:12:35:15 | x8_v |
7+
| Test.java:13:18:13:24 | tainted | Test.java:42:12:42:14 | x10 |
8+
| Test.java:49:11:49:17 | tainted | Test.java:52:12:52:16 | x11_k |
9+
| Test.java:49:11:49:17 | tainted | Test.java:59:12:59:14 | x13 |
10+
| Test.java:49:20:49:26 | tainted | Test.java:53:12:53:16 | x12_v |
11+
| Test.java:49:20:49:26 | tainted | Test.java:60:12:60:14 | x14 |
12+
| Test.java:73:11:73:17 | tainted | Test.java:75:10:75:12 | x17 |
13+
| Test.java:73:11:73:17 | tainted | Test.java:78:12:78:14 | x18 |

0 commit comments

Comments
 (0)