mirror of
https://github.com/github/codeql.git
synced 2025-12-18 01:33:15 +01:00
C#: Make implicit this receivers explicit
This commit is contained in:
@@ -14,8 +14,8 @@ import csharp
|
||||
|
||||
class CommentedOutCode extends CommentBlock {
|
||||
CommentedOutCode() {
|
||||
not isXmlCommentBlock() and
|
||||
2 * count(getAProbableCodeLine()) > count(getANonEmptyLine())
|
||||
not this.isXmlCommentBlock() and
|
||||
2 * count(this.getAProbableCodeLine()) > count(this.getANonEmptyLine())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ predicate potentiallyUsedFromXaml(RefType t) {
|
||||
|
||||
class ExportAttribute extends Attribute {
|
||||
ExportAttribute() {
|
||||
getType().hasQualifiedName("System.ComponentModel.Composition", "ExportAttribute")
|
||||
this.getType().hasQualifiedName("System.ComponentModel.Composition", "ExportAttribute")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,12 +14,12 @@ import semmle.code.csharp.frameworks.System
|
||||
|
||||
/** A call to IDisposable.Dispose or a method that overrides it. */
|
||||
class DisposeCall extends MethodCall {
|
||||
DisposeCall() { getTarget() instanceof DisposeMethod }
|
||||
DisposeCall() { this.getTarget() instanceof DisposeMethod }
|
||||
|
||||
/** The object being disposed by the call (provided it can be easily determined). */
|
||||
Variable getDisposee() {
|
||||
exists(VariableAccess va |
|
||||
va = getQualifier().stripCasts() and
|
||||
va = this.getQualifier().stripCasts() and
|
||||
result = va.getTarget()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ private predicate containerSizeAccess(PropertyAccess pa, string containerKind) {
|
||||
}
|
||||
|
||||
class ZeroLiteral extends Expr {
|
||||
ZeroLiteral() { getValue() = "0" }
|
||||
ZeroLiteral() { this.getValue() = "0" }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,9 +41,9 @@ class NonShortCircuit extends BinaryBitwiseOperation {
|
||||
this instanceof BitwiseOrExpr
|
||||
) and
|
||||
not exists(AssignBitwiseOperation abo | abo.getExpandedAssignment().getRValue() = this) and
|
||||
getLeftOperand().getType() instanceof BoolType and
|
||||
getRightOperand().getType() instanceof BoolType and
|
||||
getRightOperand() instanceof DangerousExpression
|
||||
this.getLeftOperand().getType() instanceof BoolType and
|
||||
this.getRightOperand().getType() instanceof BoolType and
|
||||
this.getRightOperand() instanceof DangerousExpression
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ abstract class BadDynamicCall extends DynamicExpr {
|
||||
abstract AssignableRead getARelevantVariableAccess(int i);
|
||||
|
||||
Type possibleBadTypeForRelevantSource(Variable v, int i, Expr source) {
|
||||
exists(Type t | t = possibleTypeForRelevantSource(v, i, source) |
|
||||
exists(Type t | t = this.possibleTypeForRelevantSource(v, i, source) |
|
||||
// If the source can have the type of an interface or an abstract class,
|
||||
// then all possible sub types are, in principle, possible
|
||||
t instanceof Interface and result.isImplicitlyConvertibleTo(t)
|
||||
@@ -37,7 +37,7 @@ abstract class BadDynamicCall extends DynamicExpr {
|
||||
|
||||
private Type possibleTypeForRelevantSource(Variable v, int i, Expr source) {
|
||||
exists(AssignableRead read, Ssa::Definition ssaDef, Ssa::ExplicitDefinition ultimateSsaDef |
|
||||
read = getARelevantVariableAccess(i) and
|
||||
read = this.getARelevantVariableAccess(i) and
|
||||
v = read.getTarget() and
|
||||
result = source.getType() and
|
||||
read = ssaDef.getARead() and
|
||||
@@ -55,28 +55,30 @@ abstract class BadDynamicCall extends DynamicExpr {
|
||||
}
|
||||
|
||||
class BadDynamicMethodCall extends BadDynamicCall, DynamicMethodCall {
|
||||
override AssignableRead getARelevantVariableAccess(int i) { result = getQualifier() and i = -1 }
|
||||
override AssignableRead getARelevantVariableAccess(int i) {
|
||||
result = this.getQualifier() and i = -1
|
||||
}
|
||||
|
||||
override predicate isBad(Variable v, ValueOrRefType pt, Expr pts, string message, string target) {
|
||||
pt = possibleBadTypeForRelevantSource(v, -1, pts) and
|
||||
not exists(Method m | m = getARuntimeTarget() |
|
||||
pt = this.possibleBadTypeForRelevantSource(v, -1, pts) and
|
||||
not exists(Method m | m = this.getARuntimeTarget() |
|
||||
pt.isImplicitlyConvertibleTo(m.getDeclaringType())
|
||||
) and
|
||||
message =
|
||||
"The $@ of this dynamic method invocation can obtain (from $@) type $@, which does not have a method '"
|
||||
+ getLateBoundTargetName() + "' with the appropriate signature." and
|
||||
+ this.getLateBoundTargetName() + "' with the appropriate signature." and
|
||||
target = "target"
|
||||
}
|
||||
}
|
||||
|
||||
class BadDynamicOperatorCall extends BadDynamicCall, DynamicOperatorCall {
|
||||
override AssignableRead getARelevantVariableAccess(int i) { result = getRuntimeArgument(i) }
|
||||
override AssignableRead getARelevantVariableAccess(int i) { result = this.getRuntimeArgument(i) }
|
||||
|
||||
override predicate isBad(Variable v, ValueOrRefType pt, Expr pts, string message, string target) {
|
||||
exists(int i |
|
||||
pt = possibleBadTypeForRelevantSource(v, i, pts) and
|
||||
pt = this.possibleBadTypeForRelevantSource(v, i, pts) and
|
||||
not pt.containsTypeParameters() and
|
||||
not exists(Type paramType | paramType = getADynamicParameterType(_, i) |
|
||||
not exists(Type paramType | paramType = this.getADynamicParameterType(_, i) |
|
||||
pt.isImplicitlyConvertibleTo(paramType)
|
||||
or
|
||||
// If either the argument type or the parameter type contains type parameters,
|
||||
@@ -93,11 +95,11 @@ class BadDynamicOperatorCall extends BadDynamicCall, DynamicOperatorCall {
|
||||
) and
|
||||
message =
|
||||
"The $@ of this dynamic operator can obtain (from $@) type $@, which does not match an operator '"
|
||||
+ getLateBoundTargetName() + "' with the appropriate signature."
|
||||
+ this.getLateBoundTargetName() + "' with the appropriate signature."
|
||||
}
|
||||
|
||||
private Type getADynamicParameterType(Operator o, int i) {
|
||||
o = getARuntimeTarget() and
|
||||
o = this.getARuntimeTarget() and
|
||||
result = o.getParameter(i).getType()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,26 +27,26 @@ class ReferenceEqualityTestOnObject extends EqualityOperation {
|
||||
// One or both of the operands has type object or interface.
|
||||
exists(getObjectOperand(this)) and
|
||||
// Neither operand is 'null'.
|
||||
not getAnOperand() instanceof NullLiteral and
|
||||
not exists(Type t | t = getAnOperand().stripImplicitCasts().getType() |
|
||||
not this.getAnOperand() instanceof NullLiteral and
|
||||
not exists(Type t | t = this.getAnOperand().stripImplicitCasts().getType() |
|
||||
t instanceof NullType or
|
||||
t instanceof ValueType
|
||||
) and
|
||||
// Neither operand is a constant - a reference comparison may well be intended for those.
|
||||
not getAnOperand().(FieldAccess).getTarget().isReadOnly() and
|
||||
not getAnOperand().hasValue() and
|
||||
not this.getAnOperand().(FieldAccess).getTarget().isReadOnly() and
|
||||
not this.getAnOperand().hasValue() and
|
||||
// Not a short-cut test in a custom `Equals` method
|
||||
not exists(EqualsMethod m |
|
||||
getEnclosingCallable() = m and
|
||||
getAnOperand() instanceof ThisAccess and
|
||||
getAnOperand() = m.getParameter(0).getAnAccess()
|
||||
this.getEnclosingCallable() = m and
|
||||
this.getAnOperand() instanceof ThisAccess and
|
||||
this.getAnOperand() = m.getParameter(0).getAnAccess()
|
||||
) and
|
||||
// Reference comparisons in Moq methods are used to define mocks
|
||||
not exists(MethodCall mc, Namespace n |
|
||||
mc.getTarget().getDeclaringType().getNamespace().getParentNamespace*() = n and
|
||||
n.hasName("Moq") and
|
||||
not exists(n.getParentNamespace()) and
|
||||
mc.getAnArgument() = getEnclosingCallable()
|
||||
mc.getAnArgument() = this.getEnclosingCallable()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ class ReferenceEqualityTestOnObject extends EqualityOperation {
|
||||
result = getObjectOperand(this) and
|
||||
// Avoid duplicate results: only include left operand if both operands
|
||||
// have object type
|
||||
(result = getRightOperand() implies not getLeftOperand() = getObjectOperand(this))
|
||||
(result = this.getRightOperand() implies not this.getLeftOperand() = getObjectOperand(this))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ abstract class LossOfPrecision extends Expr {
|
||||
Type convertedType;
|
||||
|
||||
LossOfPrecision() {
|
||||
getType() instanceof IntegralType and
|
||||
this.getType() instanceof IntegralType and
|
||||
convertedToFloatOrDecimal(this, convertedType)
|
||||
}
|
||||
|
||||
|
||||
@@ -26,11 +26,11 @@ Stmt getASuccessorStmt(Stmt s) {
|
||||
}
|
||||
|
||||
class IfThenStmt extends IfStmt {
|
||||
IfThenStmt() { not exists(getElse()) }
|
||||
IfThenStmt() { not exists(this.getElse()) }
|
||||
}
|
||||
|
||||
class IfThenElseStmt extends IfStmt {
|
||||
IfThenElseStmt() { exists(getElse()) }
|
||||
IfThenElseStmt() { exists(this.getElse()) }
|
||||
}
|
||||
|
||||
Stmt getTrailingBody(Stmt s) {
|
||||
@@ -49,16 +49,16 @@ abstract class UnbracedControlStmt extends Stmt {
|
||||
abstract Stmt getSuccessorStmt();
|
||||
|
||||
private Stmt getACandidate() {
|
||||
getSuccessorStmt() = result and
|
||||
this.getSuccessorStmt() = result and
|
||||
getBlockStmt(this) = getBlockStmt(result)
|
||||
}
|
||||
|
||||
private Location getBodyLocation() { result = getBody().getLocation() }
|
||||
private Location getBodyLocation() { result = this.getBody().getLocation() }
|
||||
|
||||
pragma[noopt]
|
||||
Stmt getAConfusingTrailingStmt() {
|
||||
result = getACandidate() and
|
||||
exists(Location l1, Location l2 | l1 = getBodyLocation() and l2 = result.getLocation() |
|
||||
result = this.getACandidate() and
|
||||
exists(Location l1, Location l2 | l1 = this.getBodyLocation() and l2 = result.getLocation() |
|
||||
// This test is slightly unreliable
|
||||
// because tabs are counted as 1 column.
|
||||
// But it's accurate enough to be useful, and will
|
||||
@@ -79,7 +79,7 @@ class UnbracedIfStmt extends UnbracedControlStmt {
|
||||
override Stmt getBody() { result = getTrailingBody(this) }
|
||||
|
||||
override Stmt getSuccessorStmt() {
|
||||
result = getASuccessorStmt(getBody()) and
|
||||
result = getASuccessorStmt(this.getBody()) and
|
||||
result != this
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ class UnbracedLoopStmt extends UnbracedControlStmt {
|
||||
|
||||
override Stmt getSuccessorStmt() {
|
||||
result = getASuccessorStmt(this) and
|
||||
result != getBody()
|
||||
result != this.getBody()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import semmle.code.csharp.frameworks.system.web.Mvc
|
||||
/** An `AuthorizationFilter` that calls the `AntiForgery.Validate` method. */
|
||||
class AntiForgeryAuthorizationFilter extends AuthorizationFilter {
|
||||
AntiForgeryAuthorizationFilter() {
|
||||
getOnAuthorizationMethod().calls*(any(AntiForgeryClass a).getValidateMethod())
|
||||
this.getOnAuthorizationMethod().calls*(any(AntiForgeryClass a).getValidateMethod())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ abstract private class OnAppendCookieTrackingConfig extends DataFlow::Configurat
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(PropertyWrite pw, Assignment a |
|
||||
pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
|
||||
pw.getProperty().getName() = propertyName() and
|
||||
pw.getProperty().getName() = this.propertyName() and
|
||||
a.getLValue() = pw and
|
||||
exists(Expr val |
|
||||
DataFlow::localExprFlow(val, a.getRValue()) and
|
||||
|
||||
@@ -150,10 +150,10 @@ class CSharpType extends TCSharpType {
|
||||
abstract string toString();
|
||||
|
||||
/** Gets a string used in IR dumps */
|
||||
string getDumpString() { result = toString() }
|
||||
string getDumpString() { result = this.toString() }
|
||||
|
||||
/** Gets the size of the type in bytes, if known. */
|
||||
final int getByteSize() { result = getIRType().getByteSize() }
|
||||
final int getByteSize() { result = this.getIRType().getByteSize() }
|
||||
|
||||
/**
|
||||
* Gets the `IRType` that represents this `CSharpType`. Many different `CSharpType`s can map to a
|
||||
@@ -168,7 +168,7 @@ class CSharpType extends TCSharpType {
|
||||
*/
|
||||
abstract predicate hasType(Type type, boolean isGLValue);
|
||||
|
||||
final predicate hasUnspecifiedType(Type type, boolean isGLValue) { hasType(type, isGLValue) }
|
||||
final predicate hasUnspecifiedType(Type type, boolean isGLValue) { this.hasType(type, isGLValue) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,7 +41,7 @@ abstract class Bound extends TBound {
|
||||
abstract Instruction getInstruction(int delta);
|
||||
|
||||
/** Gets an expression that equals this bound. */
|
||||
Instruction getInstruction() { result = getInstruction(0) }
|
||||
Instruction getInstruction() { result = this.getInstruction(0) }
|
||||
|
||||
abstract Location getLocation();
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ class NoReason extends Reason, TNoReason {
|
||||
class CondReason extends Reason, TCondReason {
|
||||
IRGuardCondition getCond() { this = TCondReason(result) }
|
||||
|
||||
override string toString() { result = getCond().toString() }
|
||||
override string toString() { result = this.getCond().toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,10 +222,10 @@ private predicate safeCast(IntegralType fromtyp, IntegralType totyp) {
|
||||
|
||||
private class SafeCastInstruction extends ConvertInstruction {
|
||||
SafeCastInstruction() {
|
||||
safeCast(getResultType(), getUnary().getResultType())
|
||||
safeCast(this.getResultType(), this.getUnary().getResultType())
|
||||
or
|
||||
getResultType() instanceof PointerType and
|
||||
getUnary().getResultType() instanceof PointerType
|
||||
this.getResultType() instanceof PointerType and
|
||||
this.getUnary().getResultType() instanceof PointerType
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,14 +260,14 @@ private predicate typeBound(IntegralType typ, int lowerbound, int upperbound) {
|
||||
private class NarrowingCastInstruction extends ConvertInstruction {
|
||||
NarrowingCastInstruction() {
|
||||
not this instanceof SafeCastInstruction and
|
||||
typeBound(getResultType(), _, _)
|
||||
typeBound(this.getResultType(), _, _)
|
||||
}
|
||||
|
||||
/** Gets the lower bound of the resulting type. */
|
||||
int getLowerBound() { typeBound(getResultType(), result, _) }
|
||||
int getLowerBound() { typeBound(this.getResultType(), result, _) }
|
||||
|
||||
/** Gets the upper bound of the resulting type. */
|
||||
int getUpperBound() { typeBound(getResultType(), _, result) }
|
||||
int getUpperBound() { typeBound(this.getResultType(), _, result) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user