Java: Make implicit this receivers explicit

This commit is contained in:
Kasper Svendsen
2023-05-03 10:08:04 +02:00
parent 733a00039e
commit 081085e128
46 changed files with 309 additions and 292 deletions

View File

@@ -18,10 +18,10 @@ import semmle.code.java.frameworks.spring.Spring
class InstanceFieldWrite extends FieldWrite {
InstanceFieldWrite() {
// Must be in an instance callable
not getEnclosingCallable().isStatic() and
not this.getEnclosingCallable().isStatic() and
// Must be declared in this type or a supertype.
getEnclosingCallable().getDeclaringType().inherits(getField()) and
isOwnFieldAccess()
this.getEnclosingCallable().getDeclaringType().inherits(this.getField()) and
this.isOwnFieldAccess()
}
}
@@ -62,7 +62,7 @@ class SpringPureClass extends Class {
SpringPureClass() {
// The only permitted statement in static initializers is the initialization of a static
// final or effectively final logger fields, or effectively immutable types.
forall(Stmt s | s = getANestedStmt(getAMember().(StaticInitializer).getBody()) |
forall(Stmt s | s = getANestedStmt(this.getAMember().(StaticInitializer).getBody()) |
exists(Field f | f = s.(ExprStmt).getExpr().(AssignExpr).getDest().(FieldWrite).getField() |
(
// A logger field
@@ -79,8 +79,8 @@ class SpringPureClass extends Class {
// No constructor, instance initializer or Spring bean init or setter method that is impure.
not exists(Callable c, ImpureStmt impureStmt |
(
inherits(c.(Method)) or
c = getAMember()
this.inherits(c.(Method)) or
c = this.getAMember()
) and
impureStmt.getEnclosingCallable() = c
|
@@ -110,7 +110,7 @@ class SpringPureClass extends Class {
*/
class SpringBeanFactory extends ClassOrInterface {
SpringBeanFactory() {
getAnAncestor().hasQualifiedName("org.springframework.beans.factory", "BeanFactory")
this.getAnAncestor().hasQualifiedName("org.springframework.beans.factory", "BeanFactory")
}
/**
@@ -136,20 +136,20 @@ class LiveSpringBean extends SpringBean {
LiveSpringBean() {
// Must not be needed for side effects due to construction
// Only loaded by the container when required, so construction cannot have any useful side-effects
not isLazyInit() and
not this.isLazyInit() and
// or has no side-effects when constructed
not getClass() instanceof SpringPureClass
not this.getClass() instanceof SpringPureClass
or
(
// If the class does not exist for this bean, or the class is not a source bean, then this is
// likely to be a definition using a library class, in which case we should consider it to be
// live.
not exists(getClass())
not exists(this.getClass())
or
not getClass().fromSource()
not this.getClass().fromSource()
or
// In alfresco, "webscript" beans should be considered live
getBeanParent*().getBeanParentName() = "webscript"
this.getBeanParent*().getBeanParentName() = "webscript"
or
// A live child bean implies this bean is live
exists(LiveSpringBean child | this = child.getBeanParent())

View File

@@ -3,8 +3,8 @@ import java
/** A class that implements `java.lang.Iterable`. */
class Iterable extends Class {
Iterable() {
isSourceDeclaration() and
getASourceSupertype+().hasQualifiedName("java.lang", "Iterable")
this.isSourceDeclaration() and
this.getASourceSupertype+().hasQualifiedName("java.lang", "Iterable")
}
/** The return value of a one-statement `iterator()` method. */

View File

@@ -16,7 +16,7 @@ import IterableClass
/** An `Iterable` that is also its own `Iterator`. */
class IterableIterator extends Iterable {
IterableIterator() { simpleIterator() instanceof ThisAccess }
IterableIterator() { this.simpleIterator() instanceof ThisAccess }
}
/** An `IterableIterator` that never returns any elements. */

View File

@@ -17,9 +17,9 @@ library class BoundKind extends string {
predicate isUpper() { this = "<=" }
predicate providesLowerBound() { isEqual() or isLower() }
predicate providesLowerBound() { this.isEqual() or this.isLower() }
predicate providesUpperBound() { isEqual() or isUpper() }
predicate providesUpperBound() { this.isEqual() or this.isUpper() }
}
/**

View File

@@ -19,19 +19,19 @@ import java
*/
class ArrayCast extends CastExpr {
ArrayCast() {
getExpr() instanceof ArrayCreationExpr and
getType() instanceof Array
this.getExpr() instanceof ArrayCreationExpr and
this.getType() instanceof Array
}
/** The type of the operand expression of this cast. */
Array getSourceType() { result = getExpr().getType() }
Array getSourceType() { result = this.getExpr().getType() }
/** The result type of this cast. */
Array getTargetType() { result = getType() }
Array getTargetType() { result = this.getType() }
Type getSourceComponentType() { result = getSourceType().getComponentType() }
Type getSourceComponentType() { result = this.getSourceType().getComponentType() }
Type getTargetComponentType() { result = getTargetType().getComponentType() }
Type getTargetComponentType() { result = this.getTargetType().getComponentType() }
}
predicate uncheckedCastType(RefType t) {

View File

@@ -32,9 +32,9 @@ class LTWideningComparison extends WideningComparison {
leftWidth(this) < rightWidth(this)
}
override Expr getNarrower() { result = getLeftOperand() }
override Expr getNarrower() { result = this.getLeftOperand() }
override Expr getWider() { result = getRightOperand() }
override Expr getWider() { result = this.getRightOperand() }
}
class GTWideningComparison extends WideningComparison {
@@ -43,9 +43,9 @@ class GTWideningComparison extends WideningComparison {
leftWidth(this) > rightWidth(this)
}
override Expr getNarrower() { result = getRightOperand() }
override Expr getNarrower() { result = this.getRightOperand() }
override Expr getWider() { result = getLeftOperand() }
override Expr getWider() { result = this.getLeftOperand() }
}
from WideningComparison c, LoopStmt l

View File

@@ -17,14 +17,14 @@ import semmle.code.java.dataflow.TaintTracking
import DataFlow
private class ShortStringLiteral extends StringLiteral {
ShortStringLiteral() { getValue().length() < 100 }
ShortStringLiteral() { this.getValue().length() < 100 }
}
class BrokenAlgoLiteral extends ShortStringLiteral {
BrokenAlgoLiteral() {
getValue().regexpMatch(getInsecureAlgorithmRegex()) and
this.getValue().regexpMatch(getInsecureAlgorithmRegex()) and
// Exclude German and French sentences.
not getValue().regexpMatch(".*\\p{IsLowercase} des \\p{IsLetter}.*")
not this.getValue().regexpMatch(".*\\p{IsLowercase} des \\p{IsLetter}.*")
}
}

View File

@@ -7,7 +7,7 @@ import semmle.code.java.dataflow.RangeAnalysis
class NumericNarrowingCastExpr extends CastExpr {
NumericNarrowingCastExpr() {
exists(NumericType sourceType, NumericType targetType |
sourceType = getExpr().getType() and targetType = getType()
sourceType = this.getExpr().getType() and targetType = this.getType()
|
not targetType.(NumType).widerThanOrEqualTo(sourceType)
)
@@ -28,8 +28,8 @@ class RightShiftOp extends Expr {
}
Variable getShiftedVariable() {
getLhs() = result.getAnAccess() or
getLhs().(AndBitwiseExpr).getAnOperand() = result.getAnAccess()
this.getLhs() = result.getAnAccess() or
this.getLhs().(AndBitwiseExpr).getAnOperand() = result.getAnAccess()
}
}

View File

@@ -17,11 +17,11 @@ class WebRequestSource extends DataFlow::Node {
m.hasName("getParameterNames") or
m.hasName("getParameterMap")
) and
ma = asExpr()
ma = this.asExpr()
)
}
}
class WebRequest extends RefType {
WebRequest() { hasQualifiedName("org.springframework.web.context.request", "WebRequest") }
WebRequest() { this.hasQualifiedName("org.springframework.web.context.request", "WebRequest") }
}

View File

@@ -24,7 +24,7 @@ class SetRevocationEnabledSink extends DataFlow::ExprNode {
SetRevocationEnabledSink() {
exists(MethodAccess setRevocationEnabledCall |
setRevocationEnabledCall.getMethod() instanceof SetRevocationEnabledMethod and
setRevocationEnabledCall.getArgument(0) = getExpr() and
setRevocationEnabledCall.getArgument(0) = this.getExpr() and
not exists(MethodAccess ma, Method m | m = ma.getMethod() |
(m instanceof AddCertPathCheckerMethod or m instanceof SetCertPathCheckersMethod) and
ma.getQualifier().(VarAccess).getVariable() =
@@ -36,25 +36,25 @@ class SetRevocationEnabledSink extends DataFlow::ExprNode {
class SetRevocationEnabledMethod extends Method {
SetRevocationEnabledMethod() {
getDeclaringType() instanceof PKIXParameters and
hasName("setRevocationEnabled")
this.getDeclaringType() instanceof PKIXParameters and
this.hasName("setRevocationEnabled")
}
}
class AddCertPathCheckerMethod extends Method {
AddCertPathCheckerMethod() {
getDeclaringType() instanceof PKIXParameters and
hasName("addCertPathChecker")
this.getDeclaringType() instanceof PKIXParameters and
this.hasName("addCertPathChecker")
}
}
class SetCertPathCheckersMethod extends Method {
SetCertPathCheckersMethod() {
getDeclaringType() instanceof PKIXParameters and
hasName("setCertPathCheckers")
this.getDeclaringType() instanceof PKIXParameters and
this.hasName("setCertPathCheckers")
}
}
class PKIXParameters extends RefType {
PKIXParameters() { hasQualifiedName("java.security.cert", "PKIXParameters") }
PKIXParameters() { this.hasQualifiedName("java.security.cert", "PKIXParameters") }
}

View File

@@ -27,7 +27,7 @@ class SslContextGetInstanceSink extends DataFlow::ExprNode {
exists(StaticMethodAccess ma, Method m | m = ma.getMethod() |
m.getDeclaringType() instanceof SslContext and
m.hasName("getInstance") and
ma.getArgument(0) = asExpr()
ma.getArgument(0) = this.asExpr()
)
}
}
@@ -39,7 +39,7 @@ class SslContextGetInstanceSink extends DataFlow::ExprNode {
class CreateSslParametersSink extends DataFlow::ExprNode {
CreateSslParametersSink() {
exists(ConstructorCall cc | cc.getConstructedType() instanceof SslParameters |
cc.getArgument(1) = asExpr()
cc.getArgument(1) = this.asExpr()
)
}
}
@@ -53,7 +53,7 @@ class SslParametersSetProtocolsSink extends DataFlow::ExprNode {
exists(MethodAccess ma, Method m | m = ma.getMethod() |
m.getDeclaringType() instanceof SslParameters and
m.hasName("setProtocols") and
ma.getArgument(0) = asExpr()
ma.getArgument(0) = this.asExpr()
)
}
}
@@ -73,7 +73,7 @@ class SetEnabledProtocolsSink extends DataFlow::ExprNode {
type instanceof SslEngine
) and
m.hasName("setEnabledProtocols") and
ma.getArgument(0) = asExpr()
ma.getArgument(0) = this.asExpr()
)
}
}
@@ -83,15 +83,15 @@ class SetEnabledProtocolsSink extends DataFlow::ExprNode {
*/
class UnsafeTlsVersion extends StringLiteral {
UnsafeTlsVersion() {
getValue() = "SSL" or
getValue() = "SSLv2" or
getValue() = "SSLv3" or
getValue() = "TLS" or
getValue() = "TLSv1" or
getValue() = "TLSv1.1"
this.getValue() = "SSL" or
this.getValue() = "SSLv2" or
this.getValue() = "SSLv3" or
this.getValue() = "TLS" or
this.getValue() = "TLSv1" or
this.getValue() = "TLSv1.1"
}
}
class SslServerSocket extends RefType {
SslServerSocket() { hasQualifiedName("javax.net.ssl", "SSLServerSocket") }
SslServerSocket() { this.hasQualifiedName("javax.net.ssl", "SSLServerSocket") }
}

View File

@@ -31,14 +31,14 @@ private predicate setsAllowCredentials(MethodAccess header) {
private class CorsProbableCheckAccess extends MethodAccess {
CorsProbableCheckAccess() {
getMethod().hasName("contains") and
getMethod().getDeclaringType().getASourceSupertype*() instanceof CollectionType
this.getMethod().hasName("contains") and
this.getMethod().getDeclaringType().getASourceSupertype*() instanceof CollectionType
or
getMethod().hasName("containsKey") and
getMethod().getDeclaringType().getASourceSupertype*() instanceof MapType
this.getMethod().hasName("containsKey") and
this.getMethod().getDeclaringType().getASourceSupertype*() instanceof MapType
or
getMethod().hasName("equals") and
getQualifier().getType() instanceof TypeString
this.getMethod().hasName("equals") and
this.getQualifier().getType() instanceof TypeString
}
}

View File

@@ -24,10 +24,10 @@ import BindingUnsafeRemoteObjectFlow::PathGraph
private class BindMethod extends Method {
BindMethod() {
(
getDeclaringType().hasQualifiedName("java.rmi", "Naming") or
getDeclaringType().hasQualifiedName("java.rmi.registry", "Registry")
this.getDeclaringType().hasQualifiedName("java.rmi", "Naming") or
this.getDeclaringType().hasQualifiedName("java.rmi.registry", "Registry")
) and
hasName(["bind", "rebind"])
this.hasName(["bind", "rebind"])
}
}