Skip to content

Commit c2a2a3a

Browse files
committed
Java: Model java.util.Optional lambda methods
Signed-off-by: Jonathan Leitschuh <[email protected]>
1 parent 1c78c79 commit c2a2a3a

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lgtm,codescanning
2+
* Added data flow models for lambda methods on `java.util.Optional`.

java/ql/lib/semmle/code/java/frameworks/Optional.qll

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,16 @@ private class OptionalModel extends SummaryModelCsv {
1515
"java.util;Optional;false;orElse;;;Argument[0];ReturnValue;value",
1616
"java.util;Optional;false;orElseGet;;;Element of Argument[-1];ReturnValue;value",
1717
"java.util;Optional;false;orElseThrow;;;Element of Argument[-1];ReturnValue;value",
18-
"java.util;Optional;false;stream;;;Element of Argument[-1];Element of ReturnValue;value"
18+
"java.util;Optional;false;stream;;;Element of Argument[-1];Element of ReturnValue;value",
19+
"java.util;Optional;false;ifPresent;;;Element of Argument[-1];Parameter[0] of Argument[0];value",
20+
"java.util;Optional;false;ifPresentOrElse;;;Element of Argument[-1];Parameter[0] of Argument[0];value",
21+
"java.util;Optional;false;map;;;Element of Argument[-1];Parameter[0] of Argument[0];value",
22+
"java.util;Optional;false;map;;;ReturnValue of Argument[0];Element of ReturnValue;value",
23+
"java.util;Optional;false;flatMap;;;Element of Argument[-1];Parameter[0] of Argument[0];value",
24+
"java.util;Optional;false;flatMap;;;ReturnValue of Argument[0];ReturnValue;value",
25+
"java.util;Optional;false;filter;;;Element of Argument[-1];Parameter[0] of Argument[0];value",
26+
"java.util;Optional;false;or;;;ReturnValue of Argument[0];ReturnValue;value",
27+
"java.util;Optional;false;orElseGet;;;ReturnValue of Argument[0];ReturnValue;value"
1928
]
2029
}
2130
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import java.util.Optional;
2+
3+
public class FunctionalTest {
4+
String source() {
5+
return null;
6+
}
7+
8+
void sink(Object o) {
9+
}
10+
11+
void test() {
12+
Optional<String> o = Optional.of(source());
13+
o.ifPresent(v -> {
14+
sink(v); // $hasValueFlow
15+
});
16+
o.ifPresentOrElse(v -> {
17+
sink(v); // $hasValueFlow
18+
}, () -> {
19+
// no-op
20+
});
21+
o.map(v -> {
22+
sink(v); // $hasValueFlow
23+
return v;
24+
}).ifPresent(v -> {
25+
sink(v); // $hasValueFlow
26+
});
27+
o.flatMap(v -> {
28+
sink(v); // $hasValueFlow
29+
return Optional.of(v);
30+
}).ifPresent(v -> {
31+
sink(v); // $hasValueFlow
32+
});
33+
o.flatMap(v -> {
34+
sink(v); // $hasValueFlow
35+
return Optional.of("safe");
36+
}).ifPresent(v -> {
37+
sink(v); // no value flow
38+
});
39+
o.filter(v -> {
40+
sink(v); // $hasValueFlow
41+
return true;
42+
}).ifPresent(v -> {
43+
sink(v); // $hasValueFlow
44+
});
45+
Optional.of("safe").map(v -> {
46+
sink(v); // no value flow
47+
return v;
48+
}).or(() -> o).ifPresent(v -> {
49+
sink(v); // $hasValueFlow
50+
});
51+
Optional<String> safe = Optional.of("safe");
52+
o.or(() -> safe).ifPresent(v -> {
53+
sink(v); // $hasValueFlow
54+
});
55+
String value = safe.orElseGet(() -> source());
56+
sink(value); // $hasValueFlow
57+
}
58+
}

0 commit comments

Comments
 (0)