-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathSynchSetUnsynchGet.ql
More file actions
56 lines (52 loc) · 1.95 KB
/
SynchSetUnsynchGet.ql
File metadata and controls
56 lines (52 loc) · 1.95 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
/**
* @name Inconsistent synchronization of getter and setter
* @description If a class has a synchronized 'set' method, and a similarly-named 'get' method is
* not also synchronized, calls to the 'get' method may not return a consistent state
* for the object.
* @kind problem
* @problem.severity error
* @precision very-high
* @id java/unsynchronized-getter
* @tags quality
* reliability
* concurrency
* language-features
* external/cwe/cwe-413
* external/cwe/cwe-662
*/
import java
/**
* Holds if this method is synchronized by a `synchronized(Foo.class){...}` block
* (for static methods) or a `synchronized(this){...}` block (for instance methods).
*/
predicate isSynchronizedByBlock(Method m) {
exists(SynchronizedStmt sync, Expr on | sync = m.getBody().getAChild*() and on = sync.getExpr() |
if m.isStatic()
then on.(TypeLiteral).getReferencedType() = m.getDeclaringType()
else on.(ThisAccess).getType().(RefType).getSourceDeclaration() = m.getDeclaringType()
)
}
/**
* Holds if `get` is a getter method for a volatile field that `set` writes to.
*
* In this case, even if `set` is synchronized and `get` is not, `get` will never see stale
* values for the field, so synchronization is optional.
*/
pragma[nomagic]
predicate bothAccessVolatileField(Method set, Method get) {
exists(Field f | f.isVolatile() |
f = get.(GetterMethod).getField() and
f.getAnAccess().(FieldWrite).getEnclosingCallable() = set
)
}
from Method set, Method get
where
set.getDeclaringType() = get.getDeclaringType() and
set.getName().matches("set%") and
get.getName() = "get" + set.getName().substring(3, set.getName().length()) and
set.isSynchronized() and
not (get.isSynchronized() or isSynchronizedByBlock(get)) and
not bothAccessVolatileField(set, get) and
set.fromSource()
select get, "This get method is unsynchronized, but the corresponding $@ is synchronized.", set,
"set method"