diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index 40e361ed1588..b5e7fd53c9fd 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -278,21 +278,23 @@ private predicate inputStreamWrapper(Constructor c, int argi) { /** An object construction that preserves the data flow status of any of its arguments. */ private predicate constructorStep(Expr tracked, ConstructorCall sink, string model) { - exists(int argi | sink.getArgument(argi) = tracked | + exists(int argi | sink.getArgument(pragma[only_bind_into](argi)) = tracked | // wrappers constructed by extension exists(Constructor c, Parameter p, SuperConstructorInvocationStmt sup | c = sink.getConstructor() and - p = c.getParameter(argi) and + p = c.getParameter(pragma[only_bind_into](argi)) and sup.getEnclosingCallable() = c and constructorStep(p.getAnAccess(), sup, model) ) or // a custom InputStream that wraps a tainted data source is tainted model = "inputStreamWrapper" and - inputStreamWrapper(sink.getConstructor(), argi) + inputStreamWrapper(sink.getConstructor(), pragma[only_bind_into](argi)) or model = "TaintPreservingCallable" and - sink.getConstructor().(TaintPreservingCallable).returnsTaintFrom(argToParam(sink, argi)) + sink.getConstructor() + .(TaintPreservingCallable) + .returnsTaintFrom(argToParam(sink, pragma[only_bind_into](argi))) ) } diff --git a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll index c07ddea6dbab..6dd49fc7ff64 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll @@ -20,8 +20,10 @@ private predicate externalStorageFlowStep(DataFlow::Node node1, DataFlow::Node n node2.asExpr().(FieldRead).getField().getInitializer() = node1.asExpr() } -private predicate externalStorageFlow(DataFlow::Node node1, DataFlow::Node node2) { - externalStorageFlowStep*(node1, node2) +private predicate externalStorageDirFlowsTo(DataFlow::Node n) { + sourceNode(n, "android-external-storage-dir") + or + exists(DataFlow::Node mid | externalStorageDirFlowsTo(mid) and externalStorageFlowStep(mid, n)) } /** @@ -29,9 +31,8 @@ private predicate externalStorageFlow(DataFlow::Node node1, DataFlow::Node node2 * This is controllable by third-party applications, so is treated as a remote flow source. */ predicate androidExternalStorageSource(DataFlow::Node n) { - exists(DataFlow::Node externalDir, DirectFileReadExpr read | - sourceNode(externalDir, "android-external-storage-dir") and + exists(DirectFileReadExpr read | n.asExpr() = read and - externalStorageFlow(externalDir, DataFlow::exprNode(read.getFileExpr())) + externalStorageDirFlowsTo(DataFlow::exprNode(read.getFileExpr())) ) } diff --git a/java/ql/src/Likely Bugs/Collections/ContainsTypeMismatch.ql b/java/ql/src/Likely Bugs/Collections/ContainsTypeMismatch.ql index 497aa10cb4de..92b257bbfc1a 100644 --- a/java/ql/src/Likely Bugs/Collections/ContainsTypeMismatch.ql +++ b/java/ql/src/Likely Bugs/Collections/ContainsTypeMismatch.ql @@ -99,14 +99,14 @@ predicate containerAccess(string package, string type, int p, string signature, class MismatchedContainerAccess extends MethodCall { MismatchedContainerAccess() { exists(string package, string type, int i | - containerAccess(package, type, _, this.getCallee().getSignature(), i) + containerAccess(package, type, _, this.getCallee().getSignature(), pragma[only_bind_into](i)) | this.getCallee() .getDeclaringType() .getSourceDeclaration() .getASourceSupertype*() .hasQualifiedName(package, type) and - this.getCallee().getParameter(i).getType() instanceof TypeObject + this.getCallee().getParameter(pragma[only_bind_into](i)).getType() instanceof TypeObject ) } diff --git a/java/ql/src/Likely Bugs/Collections/RemoveTypeMismatch.ql b/java/ql/src/Likely Bugs/Collections/RemoveTypeMismatch.ql index 54548b122e4f..8d45a93e3dd4 100644 --- a/java/ql/src/Likely Bugs/Collections/RemoveTypeMismatch.ql +++ b/java/ql/src/Likely Bugs/Collections/RemoveTypeMismatch.ql @@ -69,14 +69,15 @@ predicate containerModification(string package, string type, int p, string signa class MismatchedContainerModification extends MethodCall { MismatchedContainerModification() { exists(string package, string type, int i | - containerModification(package, type, _, this.getCallee().getSignature(), i) + containerModification(package, type, _, this.getCallee().getSignature(), + pragma[only_bind_into](i)) | this.getCallee() .getDeclaringType() .getASourceSupertype*() .getSourceDeclaration() .hasQualifiedName(package, type) and - this.getCallee().getParameter(i).getType() instanceof TypeObject + this.getCallee().getParameter(pragma[only_bind_into](i)).getType() instanceof TypeObject ) } diff --git a/java/ql/src/Likely Bugs/Frameworks/Swing/BadlyOverriddenAdapter.ql b/java/ql/src/Likely Bugs/Frameworks/Swing/BadlyOverriddenAdapter.ql index 3d4f62707344..ed3ab29c3659 100644 --- a/java/ql/src/Likely Bugs/Frameworks/Swing/BadlyOverriddenAdapter.ql +++ b/java/ql/src/Likely Bugs/Frameworks/Swing/BadlyOverriddenAdapter.ql @@ -24,14 +24,20 @@ class Adapter extends Class { } } -from Class c, Adapter adapter, Method m -where +pragma[nomagic] +predicate candidate(Class c, Adapter adapter, Method m, string name) { adapter = c.getASupertype() and c = m.getDeclaringType() and - exists(Method original | adapter = original.getDeclaringType() | m.getName() = original.getName()) and - not exists(Method overridden | adapter = overridden.getDeclaringType() | m.overrides(overridden)) and + name = m.getName() and // The method is not used for any other purpose. not exists(MethodCall ma | ma.getMethod() = m) +} + +from Class c, Adapter adapter, Method m, string name +where + candidate(c, adapter, m, name) and + exists(Method original | adapter = original.getDeclaringType() | name = original.getName()) and + not exists(Method overridden | adapter = overridden.getDeclaringType() | m.overrides(overridden)) select m, "Method " + m.getName() + " attempts to override a method in " + adapter.getName() + ", but does not have the same argument types. " + m.getName() + diff --git a/java/ql/src/Likely Bugs/Likely Typos/SelfAssignment.ql b/java/ql/src/Likely Bugs/Likely Typos/SelfAssignment.ql index 8116a906910e..fe2286aad1da 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/SelfAssignment.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/SelfAssignment.ql @@ -13,6 +13,7 @@ import java +pragma[nomagic] predicate toCompare(VarAccess left, VarAccess right) { exists(AssignExpr assign | assign.getDest() = left and assign.getSource() = right) or @@ -29,9 +30,10 @@ predicate local(RefType enclosingType, VarAccess v) { not exists(v.getQualifier()) and enclosingType = v.getEnclosingCallable().getDeclaringType() } +pragma[nomagic] predicate sameVariable(VarAccess left, VarAccess right) { toCompare(left, right) and - left.getVariable() = right.getVariable() and + pragma[only_bind_out](left.getVariable()) = pragma[only_bind_out](right.getVariable()) and ( exists(Expr q1, Expr q2 | q1 = left.getQualifier() and @@ -39,7 +41,10 @@ predicate sameVariable(VarAccess left, VarAccess right) { q2 = right.getQualifier() ) or - exists(RefType enclosingType | local(enclosingType, left) and local(enclosingType, right)) + exists(RefType enclosingType | + local(enclosingType, pragma[only_bind_out](left)) and + local(enclosingType, pragma[only_bind_out](right)) + ) ) }