-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathNonSynchronizedOverride.ql
More file actions
60 lines (56 loc) · 1.9 KB
/
NonSynchronizedOverride.ql
File metadata and controls
60 lines (56 loc) · 1.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
* @name Non-synchronized override of synchronized method
* @description If a synchronized method is overridden in a subclass, and the overriding method is
* not synchronized, the thread-safety of the subclass may be broken.
* @kind problem
* @problem.severity warning
* @precision very-high
* @id java/non-sync-override
* @tags quality
* reliability
* concurrency
* language-features
* external/cwe/cwe-820
*/
import java
/**
* Check whether expression `e` is a call to method `target` of the form
* `super.m(x, y, z)`, possibly wrapped in one or more casts and/or parentheses.
*/
predicate delegatingSuperCall(Expr e, Method target) {
exists(MethodCall call | call = e |
call.getQualifier() instanceof SuperAccess and
call.getCallee() = target and
forall(Expr arg | arg = call.getAnArgument() | arg instanceof VarAccess)
)
or
delegatingSuperCall(e.(CastingExpr).getExpr(), target)
}
/**
* Check whether method `sub` is a trivial override of method `sup` that simply
* delegates to `sup`.
*/
predicate delegatingOverride(Method sub, Method sup) {
exists(Stmt stmt |
// The body of `sub` consists of a single statement...
stmt = sub.getBody().(SingletonBlock).getStmt() and
(
// ...that is either a delegating call to `sup` (with a possible cast)...
delegatingSuperCall(stmt.(ExprStmt).getExpr(), sup)
or
// ...or a `return` statement containing such a call.
delegatingSuperCall(stmt.(ReturnStmt).getExpr(), sup)
)
)
}
from Method sub, Method sup, Class supSrc
where
sub.overrides(sup) and
sub.fromSource() and
sup.isSynchronized() and
not sub.isSynchronized() and
not delegatingOverride(sub, sup) and
supSrc = sup.getDeclaringType().getSourceDeclaration()
select sub,
"Method '" + sub.getName() + "' overrides a synchronized method in $@ but is not synchronized.",
supSrc, supSrc.getQualifiedName()