mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
C#: Make implicit this receivers explicit
This commit is contained in:
@@ -128,7 +128,7 @@ predicate missedWhereOpportunity(ForeachStmt fes, IfStmt is) {
|
||||
class AnyCall extends MethodCall {
|
||||
AnyCall() {
|
||||
exists(Method m |
|
||||
m = getTarget().getUnboundDeclaration() and
|
||||
m = this.getTarget().getUnboundDeclaration() and
|
||||
isEnumerableType(m.getDeclaringType()) and
|
||||
m.hasName("Any<>")
|
||||
)
|
||||
@@ -139,7 +139,7 @@ class AnyCall extends MethodCall {
|
||||
class CountCall extends MethodCall {
|
||||
CountCall() {
|
||||
exists(Method m |
|
||||
m = getTarget().getUnboundDeclaration() and
|
||||
m = this.getTarget().getUnboundDeclaration() and
|
||||
isEnumerableType(m.getDeclaringType()) and
|
||||
m.hasName("Count<>")
|
||||
)
|
||||
@@ -148,19 +148,19 @@ class CountCall extends MethodCall {
|
||||
|
||||
/** A variable of type IEnumerable<T>, for some T. */
|
||||
class IEnumerableSequence extends Variable {
|
||||
IEnumerableSequence() { isIEnumerableType(getType()) }
|
||||
IEnumerableSequence() { isIEnumerableType(this.getType()) }
|
||||
}
|
||||
|
||||
/** A LINQ Select(...) call. */
|
||||
class SelectCall extends ExtensionMethodCall {
|
||||
SelectCall() {
|
||||
exists(Method m |
|
||||
m = getTarget().getUnboundDeclaration() and
|
||||
m = this.getTarget().getUnboundDeclaration() and
|
||||
isEnumerableType(m.getDeclaringType()) and
|
||||
m.hasName("Select<,>")
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the anonymous function expression supplied as the argument to the Select (if possible). */
|
||||
AnonymousFunctionExpr getFunctionExpr() { result = getArgument(1) }
|
||||
AnonymousFunctionExpr getFunctionExpr() { result = this.getArgument(1) }
|
||||
}
|
||||
|
||||
@@ -38,21 +38,21 @@ class Handler extends Element, EntryPoint, @cil_handler {
|
||||
* Holds if the instruction `i` is in the scope of this handler.
|
||||
*/
|
||||
predicate isInScope(Instruction i) {
|
||||
i.getImplementation() = getImplementation() and
|
||||
i.getIndex() in [getTryStart().getIndex() .. getTryEnd().getIndex()]
|
||||
i.getImplementation() = this.getImplementation() and
|
||||
i.getIndex() in [this.getTryStart().getIndex() .. this.getTryEnd().getIndex()]
|
||||
}
|
||||
|
||||
override string toString() { none() }
|
||||
|
||||
override Instruction getASuccessorType(FlowType t) {
|
||||
result = getHandlerStart() and
|
||||
result = this.getHandlerStart() and
|
||||
t instanceof NormalFlow
|
||||
}
|
||||
|
||||
/** Gets the type of the caught exception, if any. */
|
||||
Type getCaughtType() { cil_handler_type(this, result) }
|
||||
|
||||
override Location getLocation() { result = getTryStart().getLocation() }
|
||||
override Location getLocation() { result = this.getTryStart().getLocation() }
|
||||
}
|
||||
|
||||
/** A handler corresponding to a `finally` block. */
|
||||
@@ -72,7 +72,7 @@ class FilterHandler extends Handler, @cil_filter_handler {
|
||||
|
||||
/** A handler corresponding to a `catch` clause. */
|
||||
class CatchHandler extends Handler, @cil_catch_handler {
|
||||
override string toString() { result = "catch(" + getCaughtType().getName() + ") {...}" }
|
||||
override string toString() { result = "catch(" + this.getCaughtType().getName() + ") {...}" }
|
||||
|
||||
override int getPushCount() { result = 1 }
|
||||
}
|
||||
|
||||
@@ -70,28 +70,28 @@ class XmlCommentLine extends CommentLine, @xmldoccomment {
|
||||
override string toString() { result = "/// ..." }
|
||||
|
||||
private string xmlAttributeRegex() {
|
||||
result = "(" + xmlIdentifierRegex() + ")(?:\\s*=\\s*[\"']([^\"']*)[\"'])"
|
||||
result = "(" + this.xmlIdentifierRegex() + ")(?:\\s*=\\s*[\"']([^\"']*)[\"'])"
|
||||
}
|
||||
|
||||
private string xmlIdentifierRegex() { result = "\\w+" }
|
||||
|
||||
private string xmlTagOpenRegex() { result = "<\\s*" + xmlIdentifierRegex() }
|
||||
private string xmlTagOpenRegex() { result = "<\\s*" + this.xmlIdentifierRegex() }
|
||||
|
||||
private string xmlTagIntroRegex() {
|
||||
result = xmlTagOpenRegex() + "(?:\\s*" + xmlAttributeRegex() + ")*"
|
||||
result = this.xmlTagOpenRegex() + "(?:\\s*" + this.xmlAttributeRegex() + ")*"
|
||||
}
|
||||
|
||||
private string xmlTagCloseRegex() { result = "</\\s*" + xmlIdentifierRegex() + "\\s*>" }
|
||||
private string xmlTagCloseRegex() { result = "</\\s*" + this.xmlIdentifierRegex() + "\\s*>" }
|
||||
|
||||
/** Gets the text inside the XML element at character offset `offset`. */
|
||||
private string getElement(int offset) {
|
||||
result = getText().regexpFind(xmlTagIntroRegex(), _, offset)
|
||||
result = this.getText().regexpFind(this.xmlTagIntroRegex(), _, offset)
|
||||
}
|
||||
|
||||
/** Gets the name of the opening tag at offset `offset`. */
|
||||
string getOpenTag(int offset) {
|
||||
exists(int offset1, int offset2 |
|
||||
result = getElement(offset1).regexpFind(xmlIdentifierRegex(), 0, offset2) and
|
||||
result = this.getElement(offset1).regexpFind(this.xmlIdentifierRegex(), 0, offset2) and
|
||||
offset = offset1 + offset2
|
||||
)
|
||||
}
|
||||
@@ -100,9 +100,9 @@ class XmlCommentLine extends CommentLine, @xmldoccomment {
|
||||
string getCloseTag(int offset) {
|
||||
exists(int offset1, int offset2 |
|
||||
result =
|
||||
getText()
|
||||
.regexpFind(xmlTagCloseRegex(), _, offset1)
|
||||
.regexpFind(xmlIdentifierRegex(), 0, offset2) and
|
||||
this.getText()
|
||||
.regexpFind(this.xmlTagCloseRegex(), _, offset1)
|
||||
.regexpFind(this.xmlIdentifierRegex(), 0, offset2) and
|
||||
offset = offset1 + offset2
|
||||
)
|
||||
}
|
||||
@@ -112,14 +112,14 @@ class XmlCommentLine extends CommentLine, @xmldoccomment {
|
||||
exists(int offset1, int offset2 |
|
||||
(
|
||||
result =
|
||||
getText()
|
||||
.regexpFind(xmlTagIntroRegex() + "\\s*/>", _, offset1)
|
||||
.regexpFind(xmlIdentifierRegex(), 0, offset2) or
|
||||
this.getText()
|
||||
.regexpFind(this.xmlTagIntroRegex() + "\\s*/>", _, offset1)
|
||||
.regexpFind(this.xmlIdentifierRegex(), 0, offset2) or
|
||||
result =
|
||||
getText()
|
||||
.regexpFind(xmlTagIntroRegex() + "\\s*>\\s*</" + xmlIdentifierRegex() + "\\s*>", _,
|
||||
offset1)
|
||||
.regexpFind(xmlIdentifierRegex(), 0, offset2)
|
||||
this.getText()
|
||||
.regexpFind(this.xmlTagIntroRegex() + "\\s*>\\s*</" + this.xmlIdentifierRegex() +
|
||||
"\\s*>", _, offset1)
|
||||
.regexpFind(this.xmlIdentifierRegex(), 0, offset2)
|
||||
) and
|
||||
offset = offset1 + offset2
|
||||
)
|
||||
@@ -130,18 +130,18 @@ class XmlCommentLine extends CommentLine, @xmldoccomment {
|
||||
* for a given XML attribute name `key` and element offset `offset`.
|
||||
*/
|
||||
string getAttribute(string element, string key, int offset) {
|
||||
exists(int offset1, int offset2, string elt, string pair | elt = getElement(offset1) |
|
||||
element = elt.regexpFind(xmlIdentifierRegex(), 0, offset2) and
|
||||
exists(int offset1, int offset2, string elt, string pair | elt = this.getElement(offset1) |
|
||||
element = elt.regexpFind(this.xmlIdentifierRegex(), 0, offset2) and
|
||||
offset = offset1 + offset2 and
|
||||
pair = elt.regexpFind(xmlAttributeRegex(), _, _) and
|
||||
key = pair.regexpCapture(xmlAttributeRegex(), 1) and
|
||||
result = pair.regexpCapture(xmlAttributeRegex(), 2)
|
||||
pair = elt.regexpFind(this.xmlAttributeRegex(), _, _) and
|
||||
key = pair.regexpCapture(this.xmlAttributeRegex(), 1) and
|
||||
result = pair.regexpCapture(this.xmlAttributeRegex(), 2)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if the XML element at the given offset is not empty. */
|
||||
predicate hasBody(string element, int offset) {
|
||||
element = getOpenTag(offset) and not element = getEmptyTag(offset)
|
||||
element = this.getOpenTag(offset) and not element = this.getEmptyTag(offset)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,13 +156,13 @@ class XmlCommentLine extends CommentLine, @xmldoccomment {
|
||||
*/
|
||||
class CommentBlock extends @commentblock {
|
||||
/** Gets a textual representation of this comment block. */
|
||||
string toString() { result = getChild(0).toString() }
|
||||
string toString() { result = this.getChild(0).toString() }
|
||||
|
||||
/** Gets the location of this comment block */
|
||||
Location getLocation() { commentblock_location(this, result) }
|
||||
|
||||
/** Gets the number of lines in this comment block. */
|
||||
int getNumLines() { result = count(getAChild()) }
|
||||
int getNumLines() { result = count(this.getAChild()) }
|
||||
|
||||
/** Gets the `c`th child of this comment block (numbered from 0). */
|
||||
CommentLine getChild(int c) { commentblock_child(this, result, c) }
|
||||
@@ -189,23 +189,23 @@ class CommentBlock extends @commentblock {
|
||||
Element getAnElement() { commentblock_binding(this, result, _) }
|
||||
|
||||
/** Gets a line of text in this comment block. */
|
||||
string getALine() { result = getAChild().getText() }
|
||||
string getALine() { result = this.getAChild().getText() }
|
||||
|
||||
/** Holds if the comment has no associated `Element`. */
|
||||
predicate isOrphan() { not exists(getElement()) }
|
||||
predicate isOrphan() { not exists(this.getElement()) }
|
||||
|
||||
/** Holds if this block consists entirely of XML comments. */
|
||||
predicate isXmlCommentBlock() {
|
||||
forall(CommentLine l | l = getAChild() | l instanceof XmlCommentLine)
|
||||
forall(CommentLine l | l = this.getAChild() | l instanceof XmlCommentLine)
|
||||
}
|
||||
|
||||
/** Gets a `CommentLine` containing text. */
|
||||
CommentLine getANonEmptyLine() { result = getAChild() and result.getText().length() != 0 }
|
||||
CommentLine getANonEmptyLine() { result = this.getAChild() and result.getText().length() != 0 }
|
||||
|
||||
/** Gets a `CommentLine` that might contain code. */
|
||||
CommentLine getAProbableCodeLine() {
|
||||
// Logic taken verbatim from Java query CommentedCode.qll
|
||||
result = getAChild() and
|
||||
result = this.getAChild() and
|
||||
exists(string trimmed | trimmed = result.getText().regexpReplaceAll("\\s*//.*$", "") |
|
||||
trimmed.matches("%;") or trimmed.matches("%{") or trimmed.matches("%}")
|
||||
)
|
||||
|
||||
@@ -13,25 +13,27 @@ class Compilation extends @compilation {
|
||||
Assembly getOutputAssembly() { compilation_assembly(this, result) }
|
||||
|
||||
/** Gets the folder in which this compilation was run. */
|
||||
Folder getFolder() { result.getAbsolutePath() = getDirectoryString() }
|
||||
Folder getFolder() { result.getAbsolutePath() = this.getDirectoryString() }
|
||||
|
||||
/** Gets the `i`th command line argument. */
|
||||
string getArgument(int i) { compilation_args(this, i, result) }
|
||||
|
||||
/** Gets the arguments as a concatenated string. */
|
||||
string getArguments() { result = concat(int i | exists(getArgument(i)) | getArgument(i), " ") }
|
||||
string getArguments() {
|
||||
result = concat(int i | exists(this.getArgument(i)) | this.getArgument(i), " ")
|
||||
}
|
||||
|
||||
/** Gets the 'i'th source file in this compilation. */
|
||||
File getFileCompiled(int i) { compilation_compiling_files(this, i, result) }
|
||||
|
||||
/** Gets a source file compiled in this compilation. */
|
||||
File getAFileCompiled() { result = getFileCompiled(_) }
|
||||
File getAFileCompiled() { result = this.getFileCompiled(_) }
|
||||
|
||||
/** Gets the `i`th reference in this compilation. */
|
||||
File getReference(int i) { compilation_referencing_files(this, i, result) }
|
||||
|
||||
/** Gets a reference in this compilation. */
|
||||
File getAReference() { result = getReference(_) }
|
||||
File getAReference() { result = this.getReference(_) }
|
||||
|
||||
/** Gets a diagnostic associated with this compilation. */
|
||||
Diagnostic getADiagnostic() { result.getCompilation() = this }
|
||||
@@ -40,25 +42,25 @@ class Compilation extends @compilation {
|
||||
float getMetric(int metric) { compilation_time(this, -1, metric, result) }
|
||||
|
||||
/** Gets the CPU time of the compilation. */
|
||||
float getFrontendCpuSeconds() { result = getMetric(0) }
|
||||
float getFrontendCpuSeconds() { result = this.getMetric(0) }
|
||||
|
||||
/** Gets the elapsed time of the compilation. */
|
||||
float getFrontendElapsedSeconds() { result = getMetric(1) }
|
||||
float getFrontendElapsedSeconds() { result = this.getMetric(1) }
|
||||
|
||||
/** Gets the CPU time of the extraction. */
|
||||
float getExtractorCpuSeconds() { result = getMetric(2) }
|
||||
float getExtractorCpuSeconds() { result = this.getMetric(2) }
|
||||
|
||||
/** Gets the elapsed time of the extraction. */
|
||||
float getExtractorElapsedSeconds() { result = getMetric(3) }
|
||||
float getExtractorElapsedSeconds() { result = this.getMetric(3) }
|
||||
|
||||
/** Gets the user CPU time of the compilation. */
|
||||
float getFrontendUserCpuSeconds() { result = getMetric(4) }
|
||||
float getFrontendUserCpuSeconds() { result = this.getMetric(4) }
|
||||
|
||||
/** Gets the user CPU time of the extraction. */
|
||||
float getExtractorUserCpuSeconds() { result = getMetric(5) }
|
||||
float getExtractorUserCpuSeconds() { result = this.getMetric(5) }
|
||||
|
||||
/** Gets the peak working set of the extractor process in MB. */
|
||||
float getPeakWorkingSetMB() { result = getMetric(6) }
|
||||
float getPeakWorkingSetMB() { result = this.getMetric(6) }
|
||||
|
||||
/** Gets the CPU seconds for the entire extractor process. */
|
||||
float getCpuSeconds() { compilation_finished(this, result, _) }
|
||||
|
||||
@@ -238,5 +238,7 @@ abstract deprecated class StructuralComparisonConfiguration extends string {
|
||||
* flagged as candidates for structural equality, that is,
|
||||
* `candidate(x, y)` must hold.
|
||||
*/
|
||||
predicate same(ControlFlowElement x, ControlFlowElement y) { candidate(x, y) and sameGvn(x, y) }
|
||||
predicate same(ControlFlowElement x, ControlFlowElement y) {
|
||||
this.candidate(x, y) and sameGvn(x, y)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class RuntimeCallable extends DotNet::Callable {
|
||||
RuntimeCallable() {
|
||||
not this.(Modifiable).isAbstract() and
|
||||
(
|
||||
not getDeclaringType() instanceof Interface or
|
||||
not this.getDeclaringType() instanceof Interface or
|
||||
this.(Virtualizable).isVirtual()
|
||||
)
|
||||
}
|
||||
@@ -35,7 +35,7 @@ class RuntimeMethod extends RuntimeCallable {
|
||||
|
||||
/** A run-time instance method. */
|
||||
class RuntimeInstanceMethod extends RuntimeMethod {
|
||||
RuntimeInstanceMethod() { not isStatic() }
|
||||
RuntimeInstanceMethod() { not this.isStatic() }
|
||||
}
|
||||
|
||||
/** A run-time operator. */
|
||||
@@ -46,5 +46,5 @@ class RuntimeAccessor extends Accessor, RuntimeCallable { }
|
||||
|
||||
/** A run-time instance accessor. */
|
||||
class RuntimeInstanceAccessor extends RuntimeAccessor {
|
||||
RuntimeInstanceAccessor() { not isStatic() }
|
||||
RuntimeInstanceAccessor() { not this.isStatic() }
|
||||
}
|
||||
|
||||
@@ -68,9 +68,9 @@ class RelationalOperation extends ComparisonOperation, @rel_op_expr {
|
||||
class GTExpr extends RelationalOperation, @gt_expr {
|
||||
override string getOperator() { result = ">" }
|
||||
|
||||
override Expr getGreaterOperand() { result = getLeftOperand() }
|
||||
override Expr getGreaterOperand() { result = this.getLeftOperand() }
|
||||
|
||||
override Expr getLesserOperand() { result = getRightOperand() }
|
||||
override Expr getLesserOperand() { result = this.getRightOperand() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "GTExpr" }
|
||||
}
|
||||
@@ -81,9 +81,9 @@ class GTExpr extends RelationalOperation, @gt_expr {
|
||||
class LTExpr extends RelationalOperation, @lt_expr {
|
||||
override string getOperator() { result = "<" }
|
||||
|
||||
override Expr getGreaterOperand() { result = getRightOperand() }
|
||||
override Expr getGreaterOperand() { result = this.getRightOperand() }
|
||||
|
||||
override Expr getLesserOperand() { result = getLeftOperand() }
|
||||
override Expr getLesserOperand() { result = this.getLeftOperand() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "LTExpr" }
|
||||
}
|
||||
@@ -94,9 +94,9 @@ class LTExpr extends RelationalOperation, @lt_expr {
|
||||
class GEExpr extends RelationalOperation, @ge_expr {
|
||||
override string getOperator() { result = ">=" }
|
||||
|
||||
override Expr getGreaterOperand() { result = getLeftOperand() }
|
||||
override Expr getGreaterOperand() { result = this.getLeftOperand() }
|
||||
|
||||
override Expr getLesserOperand() { result = getRightOperand() }
|
||||
override Expr getLesserOperand() { result = this.getRightOperand() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "GEExpr" }
|
||||
}
|
||||
@@ -107,9 +107,9 @@ class GEExpr extends RelationalOperation, @ge_expr {
|
||||
class LEExpr extends RelationalOperation, @le_expr {
|
||||
override string getOperator() { result = "<=" }
|
||||
|
||||
override Expr getGreaterOperand() { result = getRightOperand() }
|
||||
override Expr getGreaterOperand() { result = this.getRightOperand() }
|
||||
|
||||
override Expr getLesserOperand() { result = getLeftOperand() }
|
||||
override Expr getLesserOperand() { result = this.getLeftOperand() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "LEExpr" }
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ private import semmle.code.csharp.frameworks.system.security.cryptography.Symmet
|
||||
|
||||
/** Array of type Byte */
|
||||
deprecated class ByteArray extends ArrayType {
|
||||
ByteArray() { getElementType() instanceof ByteType }
|
||||
ByteArray() { this.getElementType() instanceof ByteType }
|
||||
}
|
||||
|
||||
/** Abstract class for all sources of keys */
|
||||
@@ -31,7 +31,7 @@ abstract class KeySanitizer extends DataFlow::ExprNode { }
|
||||
*/
|
||||
class SymmetricEncryptionKeyPropertySink extends SymmetricEncryptionKeySink {
|
||||
SymmetricEncryptionKeyPropertySink() {
|
||||
exists(SymmetricAlgorithm ag | asExpr() = ag.getKeyProperty().getAnAssignedValue())
|
||||
exists(SymmetricAlgorithm ag | this.asExpr() = ag.getKeyProperty().getAnAssignedValue())
|
||||
}
|
||||
|
||||
override string getDescription() { result = "Key property assignment" }
|
||||
@@ -43,7 +43,7 @@ class SymmetricEncryptionKeyPropertySink extends SymmetricEncryptionKeySink {
|
||||
class SymmetricEncryptionCreateEncryptorSink extends SymmetricEncryptionKeySink {
|
||||
SymmetricEncryptionCreateEncryptorSink() {
|
||||
exists(SymmetricAlgorithm ag, MethodCall mc | mc = ag.getASymmetricEncryptor() |
|
||||
asExpr() = mc.getArgumentForName("rgbKey")
|
||||
this.asExpr() = mc.getArgumentForName("rgbKey")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class SymmetricEncryptionCreateEncryptorSink extends SymmetricEncryptionKeySink
|
||||
class SymmetricEncryptionCreateDecryptorSink extends SymmetricEncryptionKeySink {
|
||||
SymmetricEncryptionCreateDecryptorSink() {
|
||||
exists(SymmetricAlgorithm ag, MethodCall mc | mc = ag.getASymmetricDecryptor() |
|
||||
asExpr() = mc.getArgumentForName("rgbKey")
|
||||
this.asExpr() = mc.getArgumentForName("rgbKey")
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@ private class KnownType extends Type {
|
||||
}
|
||||
|
||||
class TypeRef extends @typeref {
|
||||
string toString() { hasName(result) }
|
||||
string toString() { this.hasName(result) }
|
||||
|
||||
predicate hasName(string name) { typerefs(this, name) }
|
||||
|
||||
@@ -13,7 +13,7 @@ class TypeRef extends @typeref {
|
||||
}
|
||||
|
||||
class MissingType extends TypeRef {
|
||||
MissingType() { not exists(getType()) }
|
||||
MissingType() { not exists(this.getType()) }
|
||||
}
|
||||
|
||||
from
|
||||
|
||||
Reference in New Issue
Block a user