mirror of
https://github.com/github/codeql.git
synced 2026-05-03 12:45:27 +02:00
Java: Change TCs of Stmt.getParent to Stmt.getEnclosingStmt.
This commit is contained in:
committed by
yh-semmle
parent
6ecf46ce85
commit
0a569f6c1a
@@ -17,7 +17,7 @@ import semmle.code.java.JDK
|
||||
class CheckedCast extends CastExpr {
|
||||
CheckedCast() {
|
||||
exists(TryStmt try, RefType cce |
|
||||
this.getEnclosingStmt().getParent+() = try and
|
||||
this.getEnclosingStmt().getEnclosingStmt+() = try and
|
||||
try.getACatchClause().getVariable().getType() = cce and
|
||||
cce.getQualifiedName() = "java.lang.ClassCastException"
|
||||
)
|
||||
|
||||
@@ -69,8 +69,8 @@ class DangerStmt extends Stmt {
|
||||
|
||||
from WhileStmt s, DangerStmt d
|
||||
where
|
||||
d.getParent+() = s and
|
||||
d.getEnclosingStmt+() = s and
|
||||
not exists(MethodAccess call | callsCommunicationMethod(call.getMethod()) |
|
||||
call.getEnclosingStmt().getParent*() = s
|
||||
call.getEnclosingStmt().getEnclosingStmt*() = s
|
||||
)
|
||||
select d, "Prefer wait/notify or java.util.concurrent to communicate between threads."
|
||||
|
||||
@@ -33,7 +33,7 @@ where
|
||||
1 = strictcount(FieldAccess fa |
|
||||
fa.getField() = f and
|
||||
fa.getEnclosingCallable() = sync.getEnclosingCallable() and
|
||||
not fa.getEnclosingStmt().getParent*() = sync.getBlock()
|
||||
not fa.getEnclosingStmt().getEnclosingStmt*() = sync.getBlock()
|
||||
)
|
||||
)
|
||||
select sync, "Double-checked locking on the non-volatile field $@ is not thread-safe.", f,
|
||||
|
||||
@@ -35,8 +35,8 @@ private Expr getANullCheck(Field f) {
|
||||
* as they are always safe to initialize with double-checked locking.
|
||||
*/
|
||||
predicate doubleCheckedLocking(IfStmt if1, IfStmt if2, SynchronizedStmt sync, Field f) {
|
||||
if1.getThen() = sync.getParent*() and
|
||||
sync.getBlock() = if2.getParent*() and
|
||||
if1.getThen() = sync.getEnclosingStmt*() and
|
||||
sync.getBlock() = if2.getEnclosingStmt*() and
|
||||
if1.getCondition() = getANullCheck(f) and
|
||||
if2.getCondition() = getANullCheck(f)
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ class SideEffect extends Expr {
|
||||
from IfStmt if1, IfStmt if2, SynchronizedStmt sync, Field f, AssignExpr a, SideEffect se
|
||||
where
|
||||
doubleCheckedLocking(if1, if2, sync, f) and
|
||||
a.getEnclosingStmt().getParent*() = if2.getThen() and
|
||||
se.getEnclosingStmt().getParent*() = sync.getBlock() and
|
||||
a.getEnclosingStmt().getEnclosingStmt*() = if2.getThen() and
|
||||
se.getEnclosingStmt().getEnclosingStmt*() = sync.getBlock() and
|
||||
a.(ControlFlowNode).getASuccessor+() = se and
|
||||
a.getDest().(FieldAccess).getField() = f
|
||||
select a,
|
||||
|
||||
@@ -23,6 +23,6 @@ from SynchronizedStmt s, Field f, Assignment a
|
||||
where
|
||||
synchField(s) = f and
|
||||
assignmentToField(a) = f and
|
||||
a.getEnclosingStmt().getParent*() = s
|
||||
a.getEnclosingStmt().getEnclosingStmt*() = s
|
||||
select a, "Synchronization on field $@ in futile attempt to guard that field.", f,
|
||||
f.getDeclaringType().getName() + "." + f.getName()
|
||||
|
||||
@@ -24,7 +24,7 @@ predicate withinInitializer(Expr e) {
|
||||
}
|
||||
|
||||
predicate locallySynchronized(MethodAccess ma) {
|
||||
ma.getEnclosingStmt().getParent+() instanceof SynchronizedStmt
|
||||
ma.getEnclosingStmt().getEnclosingStmt+() instanceof SynchronizedStmt
|
||||
}
|
||||
|
||||
predicate hasUnsynchronizedCall(Method m) {
|
||||
@@ -41,7 +41,7 @@ predicate hasUnsynchronizedCall(Method m) {
|
||||
|
||||
predicate withinLocalSynchronization(Expr e) {
|
||||
e.getEnclosingCallable().isSynchronized() or
|
||||
e.getEnclosingStmt().getParent+() instanceof SynchronizedStmt
|
||||
e.getEnclosingStmt().getEnclosingStmt+() instanceof SynchronizedStmt
|
||||
}
|
||||
|
||||
class MyField extends Field {
|
||||
|
||||
@@ -94,14 +94,14 @@ where
|
||||
not method instanceof StaticInitializer and
|
||||
// There must be an unsynchronized read.
|
||||
exists(IfStmt unsyncNullCheck | unsyncNullCheck = init.getAnEnclosingNullCheck() |
|
||||
not unsyncNullCheck.getParent+() instanceof ValidSynchStmt
|
||||
not unsyncNullCheck.getEnclosingStmt+() instanceof ValidSynchStmt
|
||||
) and
|
||||
if i.getParent+() instanceof ValidSynchStmt
|
||||
if i.getEnclosingStmt+() instanceof ValidSynchStmt
|
||||
then (
|
||||
not init.getField().isVolatile() and
|
||||
message = "The field must be volatile."
|
||||
) else (
|
||||
if i.getParent+() instanceof SynchronizedStmt
|
||||
if i.getEnclosingStmt+() instanceof SynchronizedStmt
|
||||
then message = "Bad synchronization."
|
||||
else message = "Missing synchronization."
|
||||
)
|
||||
|
||||
@@ -20,7 +20,7 @@ where
|
||||
sleep.hasName("sleep") and
|
||||
sleep.getDeclaringType().hasQualifiedName("java.lang", "Thread") and
|
||||
(
|
||||
ma.getEnclosingStmt().getParent*() instanceof SynchronizedStmt or
|
||||
ma.getEnclosingStmt().getEnclosingStmt*() instanceof SynchronizedStmt or
|
||||
ma.getEnclosingCallable().isSynchronized()
|
||||
)
|
||||
select ma, "sleep() with lock held."
|
||||
|
||||
@@ -23,5 +23,5 @@ class WaitMethod extends Method {
|
||||
from MethodAccess ma
|
||||
where
|
||||
ma.getMethod() instanceof WaitMethod and
|
||||
not exists(LoopStmt s | ma.getEnclosingStmt().getParent*() = s)
|
||||
not exists(LoopStmt s | ma.getEnclosingStmt().getEnclosingStmt*() = s)
|
||||
select ma, "To avoid spurious wake-ups, 'wait' should only be called inside a loop."
|
||||
|
||||
@@ -25,6 +25,6 @@ from MethodAccess ma, SynchronizedStmt synch
|
||||
where
|
||||
ma.getMethod().hasName("wait") and
|
||||
ma.getMethod().getDeclaringType().hasQualifiedName("java.lang", "Object") and
|
||||
ma.getEnclosingStmt().getParent*() = synch and
|
||||
synch.getParent+() instanceof Synched
|
||||
ma.getEnclosingStmt().getEnclosingStmt*() = synch and
|
||||
synch.getEnclosingStmt+() instanceof Synched
|
||||
select ma, "wait() with two locks held."
|
||||
|
||||
@@ -17,7 +17,7 @@ from ForStmt inner, Variable iteration, ForStmt outer
|
||||
where
|
||||
iteration = inner.getAnIterationVariable() and
|
||||
iteration = outer.getAnIterationVariable() and
|
||||
inner.getParent+() = outer and
|
||||
inner.getEnclosingStmt+() = outer and
|
||||
inner.getBasicBlock().getABBSuccessor+() = outer.getCondition().getBasicBlock()
|
||||
select inner.getCondition(), "Nested for statement uses loop variable $@ of enclosing $@.",
|
||||
iteration, iteration.getName(), outer, "for statement"
|
||||
|
||||
@@ -19,8 +19,8 @@ import java
|
||||
* and are therefore not propagated to the outer try block `t`.
|
||||
*/
|
||||
private predicate caughtInside(TryStmt t, Stmt s, RefType rt) {
|
||||
exists(TryStmt innerTry | innerTry.getParent+() = t.getBlock() |
|
||||
s.getParent+() = innerTry.getBlock() and
|
||||
exists(TryStmt innerTry | innerTry.getEnclosingStmt+() = t.getBlock() |
|
||||
s.getEnclosingStmt+() = innerTry.getBlock() and
|
||||
caughtType(innerTry, _).hasSubtype*(rt)
|
||||
)
|
||||
}
|
||||
@@ -43,7 +43,7 @@ private RefType getAThrownExceptionType(TryStmt t) {
|
||||
)
|
||||
or
|
||||
exists(Call call, Exception e |
|
||||
t.getBlock() = call.getEnclosingStmt().getParent*() or
|
||||
t.getBlock() = call.getEnclosingStmt().getEnclosingStmt*() or
|
||||
t.getAResourceDecl() = call.getEnclosingStmt()
|
||||
|
|
||||
(
|
||||
@@ -55,7 +55,7 @@ private RefType getAThrownExceptionType(TryStmt t) {
|
||||
)
|
||||
or
|
||||
exists(ThrowStmt ts |
|
||||
t.getBlock() = ts.getParent*() and
|
||||
t.getBlock() = ts.getEnclosingStmt*() and
|
||||
not caughtInside(t, ts, ts.getExpr().getType()) and
|
||||
result = ts.getExpr().getType()
|
||||
)
|
||||
|
||||
@@ -29,10 +29,10 @@ predicate loopWhileTrue(LoopStmt loop) {
|
||||
* is worth flagging even if it has a reachable exceptional loop exit.
|
||||
*/
|
||||
predicate loopExit(LoopStmt loop, Stmt exit) {
|
||||
exit.getParent*() = loop.getBody() and
|
||||
exit.getEnclosingStmt*() = loop.getBody() and
|
||||
(
|
||||
exit instanceof ReturnStmt or
|
||||
exit.(BreakStmt).(JumpStmt).getTarget() = loop.getParent*()
|
||||
exit.(BreakStmt).(JumpStmt).getTarget() = loop.getEnclosingStmt*()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ predicate loopExit(LoopStmt loop, Stmt exit) {
|
||||
predicate loopExitGuard(LoopStmt loop, Expr cond) {
|
||||
exists(ConditionBlock cb, boolean branch |
|
||||
cond = cb.getCondition() and
|
||||
cond.getEnclosingStmt().getParent*() = loop.getBody() and
|
||||
cond.getEnclosingStmt().getEnclosingStmt*() = loop.getBody() and
|
||||
forex(Stmt exit | loopExit(loop, exit) | cb.controls(exit.getBasicBlock(), branch))
|
||||
)
|
||||
}
|
||||
@@ -60,7 +60,7 @@ predicate mainLoopCondition(LoopStmt loop, Expr cond) {
|
||||
then loopReentry = loop.(ForStmt).getUpdate(0)
|
||||
else loopReentry = cond
|
||||
|
|
||||
last.getEnclosingStmt().getParent*() = loop.getBody() and
|
||||
last.getEnclosingStmt().getEnclosingStmt*() = loop.getBody() and
|
||||
last.getASuccessor().(Expr).getParent*() = loopReentry
|
||||
)
|
||||
}
|
||||
@@ -74,7 +74,7 @@ where
|
||||
) and
|
||||
// None of the ssa variables in `cond` are updated inside the loop.
|
||||
forex(SsaVariable ssa, RValue use | ssa.getAUse() = use and use.getParent*() = cond |
|
||||
not ssa.getCFGNode().getEnclosingStmt().getParent*() = loop or
|
||||
not ssa.getCFGNode().getEnclosingStmt().getEnclosingStmt*() = loop or
|
||||
ssa.getCFGNode().(Expr).getParent*() = loop.(ForStmt).getAnInit()
|
||||
) and
|
||||
// And `cond` does not use method calls, field reads, or array reads.
|
||||
|
||||
@@ -48,7 +48,7 @@ predicate useAndDef(Assignment a, Variable v) {
|
||||
predicate declaredInLoop(LocalVariableDecl v, LoopStmt loop) {
|
||||
exists(LocalVariableDeclExpr e |
|
||||
e.getVariable() = v and
|
||||
e.getEnclosingStmt().getParent*() = loop.getBody()
|
||||
e.getEnclosingStmt().getEnclosingStmt*() = loop.getBody()
|
||||
)
|
||||
or
|
||||
exists(EnhancedForStmt for | for = loop | for.getVariable().getVariable() = v)
|
||||
@@ -57,5 +57,5 @@ predicate declaredInLoop(LocalVariableDecl v, LoopStmt loop) {
|
||||
from Assignment a, Variable v
|
||||
where
|
||||
useAndDef(a, v) and
|
||||
exists(LoopStmt loop | a.getEnclosingStmt().getParent*() = loop | not declaredInLoop(v, loop))
|
||||
exists(LoopStmt loop | a.getEnclosingStmt().getEnclosingStmt*() = loop | not declaredInLoop(v, loop))
|
||||
select a, "The string " + v.getName() + " is built-up in a loop: use string buffer."
|
||||
|
||||
@@ -46,7 +46,7 @@ class Synched extends Top {
|
||||
or
|
||||
result = this.(SynchronizedStmt).getAChild+()
|
||||
or
|
||||
exists(MethodAccess ma | ma = result | ma.getEnclosingStmt().getParent*() = this)
|
||||
exists(MethodAccess ma | ma = result | ma.getEnclosingStmt().getEnclosingStmt*() = this)
|
||||
}
|
||||
|
||||
/** The variable on which synchronization is performed, provided this element is a `SynchronizedStmt`. */
|
||||
|
||||
@@ -22,16 +22,16 @@ predicate loopCondition(LoopStmt loop, Expr cond, boolean polarity) {
|
||||
polarity = true and cond = loop.getCondition()
|
||||
or
|
||||
exists(IfStmt ifstmt, Stmt exit |
|
||||
ifstmt.getParent*() = loop.getBody() and
|
||||
ifstmt.getEnclosingStmt*() = loop.getBody() and
|
||||
ifstmt.getCondition() = cond and
|
||||
(
|
||||
exit.(BreakStmt).(JumpStmt).getTarget() = loop or
|
||||
exit.(ReturnStmt).getParent*() = loop.getBody()
|
||||
exit.(ReturnStmt).getEnclosingStmt*() = loop.getBody()
|
||||
) and
|
||||
(
|
||||
polarity = false and exit.getParent*() = ifstmt.getThen()
|
||||
polarity = false and exit.getEnclosingStmt*() = ifstmt.getThen()
|
||||
or
|
||||
polarity = true and exit.getParent*() = ifstmt.getElse()
|
||||
polarity = true and exit.getEnclosingStmt*() = ifstmt.getElse()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -22,19 +22,19 @@ private predicate relevantTypeNames(string typeName, string message) {
|
||||
|
||||
private Type getAThrownExceptionType(TryStmt t) {
|
||||
exists(MethodAccess ma, Exception e |
|
||||
t.getBlock() = ma.getEnclosingStmt().getParent*() and
|
||||
t.getBlock() = ma.getEnclosingStmt().getEnclosingStmt*() and
|
||||
ma.getMethod().getAnException() = e and
|
||||
result = e.getType()
|
||||
)
|
||||
or
|
||||
exists(ClassInstanceExpr cie, Exception e |
|
||||
t.getBlock() = cie.getEnclosingStmt().getParent*() and
|
||||
t.getBlock() = cie.getEnclosingStmt().getEnclosingStmt*() and
|
||||
cie.getConstructor().getAnException() = e and
|
||||
result = e.getType()
|
||||
)
|
||||
or
|
||||
exists(ThrowStmt ts |
|
||||
t.getBlock() = ts.getParent*() and
|
||||
t.getBlock() = ts.getEnclosingStmt*() and
|
||||
result = ts.getExpr().getType()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ from Expr e
|
||||
where
|
||||
throwsNFE(e) and
|
||||
not exists(TryStmt t |
|
||||
t.getBlock() = e.getEnclosingStmt().getParent*() and
|
||||
t.getBlock() = e.getEnclosingStmt().getEnclosingStmt*() and
|
||||
catchesNFE(t)
|
||||
) and
|
||||
not exists(Callable c |
|
||||
|
||||
@@ -28,7 +28,7 @@ predicate guardedByInstanceOf(VarAccess e, RefType t) {
|
||||
// The expression appears in one of the branches.
|
||||
// (We do not verify here whether the guard is correctly implemented.)
|
||||
exists(Stmt branch | branch = s.getThen() or branch = s.getElse() |
|
||||
branch = e.getEnclosingStmt().getParent+()
|
||||
branch = e.getEnclosingStmt().getEnclosingStmt+()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import java
|
||||
* Holds if `e` is synchronized by a local synchronized statement `sync` on the variable `v`.
|
||||
*/
|
||||
predicate locallySynchronizedOn(Expr e, SynchronizedStmt sync, Variable v) {
|
||||
e.getEnclosingStmt().getParent+() = sync and
|
||||
e.getEnclosingStmt().getEnclosingStmt+() = sync and
|
||||
sync.getExpr().(VarAccess).getVariable() = v
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ predicate locallySynchronizedOn(Expr e, SynchronizedStmt sync, Variable v) {
|
||||
* modifier on the enclosing (non-static) method.
|
||||
*/
|
||||
predicate locallySynchronizedOnThis(Expr e, RefType thisType) {
|
||||
exists(SynchronizedStmt sync | e.getEnclosingStmt().getParent+() = sync |
|
||||
exists(SynchronizedStmt sync | e.getEnclosingStmt().getEnclosingStmt+() = sync |
|
||||
sync.getExpr().getProperExpr().(ThisAccess).getType().(RefType).getSourceDeclaration() = thisType
|
||||
)
|
||||
or
|
||||
|
||||
@@ -184,7 +184,7 @@ private predicate varMaybeNull(SsaVariable v, string msg, Expr reason) {
|
||||
not v instanceof SsaPhiNode and
|
||||
not clearlyNotNull(v) and
|
||||
// Comparisons in finally blocks are excluded since missing exception edges in the CFG could otherwise yield FPs.
|
||||
not exists(TryStmt try | try.getFinally() = e.getEnclosingStmt().getParent*()) and
|
||||
not exists(TryStmt try | try.getFinally() = e.getEnclosingStmt().getEnclosingStmt*()) and
|
||||
(
|
||||
exists(ConditionalExpr c | c.getCondition().getAChildExpr*() = e) or
|
||||
not exists(MethodAccess ma | ma.getAnArgument().getAChildExpr*() = e)
|
||||
@@ -291,8 +291,8 @@ private predicate leavingFinally(BasicBlock bb1, BasicBlock bb2, boolean normale
|
||||
exists(TryStmt try, Block finally |
|
||||
try.getFinally() = finally and
|
||||
bb1.getABBSuccessor() = bb2 and
|
||||
bb1.getEnclosingStmt().getParent*() = finally and
|
||||
not bb2.getEnclosingStmt().getParent*() = finally and
|
||||
bb1.getEnclosingStmt().getEnclosingStmt*() = finally and
|
||||
not bb2.getEnclosingStmt().getEnclosingStmt*() = finally and
|
||||
if bb1.getLastNode().getANormalSuccessor() = bb2.getFirstNode()
|
||||
then normaledge = true
|
||||
else normaledge = false
|
||||
|
||||
@@ -166,7 +166,7 @@ private module TrackedVariablesImpl {
|
||||
/** Holds if `f` is accessed inside a loop. */
|
||||
private predicate loopAccessed(SsaSourceField f) {
|
||||
exists(LoopStmt l, FieldRead fr | fr = f.getAnAccess() |
|
||||
l.getBody() = fr.getEnclosingStmt().getParent*() or
|
||||
l.getBody() = fr.getEnclosingStmt().getEnclosingStmt*() or
|
||||
l.getCondition() = fr.getParent*() or
|
||||
l.(ForStmt).getAnUpdate() = fr.getParent*()
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user