Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions csharp/ql/src/API Abuse/CallToGCCollect.ql
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
* @tags efficiency
* maintainability
*/

import csharp

from MethodCall c, Method gcCollect
where
c.getTarget() = gcCollect
and gcCollect.hasName("Collect")
and gcCollect.hasNoParameters()
and gcCollect.getDeclaringType().hasQualifiedName("System.GC")
c.getTarget() = gcCollect and
gcCollect.hasName("Collect") and
gcCollect.hasNoParameters() and
gcCollect.getDeclaringType().hasQualifiedName("System.GC")
select c, "Call to 'GC.Collect()'."
11 changes: 5 additions & 6 deletions csharp/ql/src/API Abuse/CallToObsoleteMethod.ql
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@
import csharp

class ObsoleteAttribute extends Attribute {
ObsoleteAttribute() {
this.getType().hasQualifiedName("System", "ObsoleteAttribute")
}
ObsoleteAttribute() { this.getType().hasQualifiedName("System", "ObsoleteAttribute") }
}

from MethodCall c, Method m
where m = c.getTarget()
and m.getAnAttribute() instanceof ObsoleteAttribute
and not c.getEnclosingCallable().(Attributable).getAnAttribute() instanceof ObsoleteAttribute
where
m = c.getTarget() and
m.getAnAttribute() instanceof ObsoleteAttribute and
not c.getEnclosingCallable().(Attributable).getAnAttribute() instanceof ObsoleteAttribute
select c, "Call to obsolete method $@.", m, m.getName()
40 changes: 21 additions & 19 deletions csharp/ql/src/API Abuse/ClassDoesNotImplementEquals.ql
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,30 @@ import semmle.code.csharp.frameworks.System

from Class c, Element item, string message, string itemText
where
c.isSourceDeclaration()
and not implementsEquals(c)
and not c.isAbstract()
and
c.isSourceDeclaration() and
not implementsEquals(c) and
not c.isAbstract() and
(
exists(MethodCall callToEquals |
callToEquals.getTarget() instanceof EqualsMethod
and callToEquals.getQualifier().getType() = c
and message = "but it is called $@"
and item = callToEquals
and itemText = "here" )
callToEquals.getTarget() instanceof EqualsMethod and
callToEquals.getQualifier().getType() = c and
message = "but it is called $@" and
item = callToEquals and
itemText = "here"
)
or
( item = c.getAnOperator().(EQOperator)
and message = "but it implements $@"
and itemText = "operator ==" )
(
item = c.getAnOperator().(EQOperator) and
message = "but it implements $@" and
itemText = "operator =="
)
or
exists(IEquatableEqualsMethod eq | item = eq
and eq = c.getAMethod()
and message = "but it implements $@"
and itemText = "IEquatable<" + eq.getParameter(0).getType() + ">.Equals"
exists(IEquatableEqualsMethod eq |
item = eq and
eq = c.getAMethod() and
message = "but it implements $@" and
itemText = "IEquatable<" + eq.getParameter(0).getType() + ">.Equals"
)
)

select c, "Class '" + c.getName() + "' does not implement Equals(object), " + message + ".",
item, itemText
select c, "Class '" + c.getName() + "' does not implement Equals(object), " + message + ".", item,
itemText
8 changes: 4 additions & 4 deletions csharp/ql/src/API Abuse/ClassImplementsICloneable.ql
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import csharp

from ValueOrRefType c
where
c.fromSource()
and c.getABaseInterface+().hasQualifiedName("System", "ICloneable")
and not c.isSealed()
and exists(Method m | m.getDeclaringType() = c and m.hasName("Clone"))
c.fromSource() and
c.getABaseInterface+().hasQualifiedName("System", "ICloneable") and
not c.isSealed() and
exists(Method m | m.getDeclaringType() = c and m.hasName("Clone"))
select c, "Class '" + c.getName() + "' implements 'ICloneable'."
34 changes: 20 additions & 14 deletions csharp/ql/src/API Abuse/DisposeNotCalledOnException.ql
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ ExceptionClass getAThrownException(Method m) {
or
exists(ControlFlowElement cfe |
cfe = any(ThrowElement te | result = te.getExpr().getType()) or
cfe = any(MethodCall mc | result = getAThrownException(mc.getARuntimeTarget())) |
cfe = any(MethodCall mc | result = getAThrownException(mc.getARuntimeTarget()))
|
cfe.getEnclosingCallable() = m and
not isTriedAgainstException(cfe, result)
)
Expand All @@ -39,7 +40,7 @@ ExceptionClass getAThrownException(Method m) {
* Holds if control flow element is tried against throwing an exception of type
* `ec`.
*/
pragma [noinline]
pragma[noinline]
predicate isTriedAgainstException(ControlFlowElement cfe, ExceptionClass ec) {
(cfe instanceof ThrowElement or cfe instanceof MethodCall) and
exists(TryStmt ts |
Expand All @@ -53,22 +54,27 @@ predicate isTriedAgainstException(ControlFlowElement cfe, ExceptionClass ec) {
*/
predicate disposeReachableFromDisposableCreation(MethodCall disposeCall, Expr disposableCreation) {
// The qualifier of the Dispose call flows from something that introduced a disposable into scope
(disposableCreation instanceof LocalScopeDisposableCreation or disposableCreation instanceof MethodCall)
and DataFlow::localFlowStep+(DataFlow::exprNode(disposableCreation), DataFlow::exprNode(disposeCall.getQualifier()))
and disposeCall.getTarget() instanceof DisposeMethod
(
disposableCreation instanceof LocalScopeDisposableCreation or
disposableCreation instanceof MethodCall
) and
DataFlow::localFlowStep+(DataFlow::exprNode(disposableCreation),
DataFlow::exprNode(disposeCall.getQualifier())) and
disposeCall.getTarget() instanceof DisposeMethod
}


from MethodCall disposeCall, Expr disposableCreation, MethodCall callThatThrows
where
disposeReachableFromDisposableCreation(disposeCall, disposableCreation)
disposeReachableFromDisposableCreation(disposeCall, disposableCreation) and
// The dispose call is not, itself, within a dispose method.
and not disposeCall.getEnclosingCallable() instanceof DisposeMethod
not disposeCall.getEnclosingCallable() instanceof DisposeMethod and
// Dispose call not within a finally or catch block
and not exists(TryStmt ts |
ts.getACatchClause().getAChild*() = disposeCall or ts.getFinally().getAChild*() = disposeCall)
not exists(TryStmt ts |
ts.getACatchClause().getAChild*() = disposeCall or ts.getFinally().getAChild*() = disposeCall
) and
// At least one method call exists between the allocation and disposal that could throw
and disposableCreation.getAReachableElement() = callThatThrows
and callThatThrows.getAReachableElement() = disposeCall
and exists(getAThrownException(callThatThrows.getARuntimeTarget()))
select disposeCall, "Dispose missed if exception is thrown by $@.", callThatThrows, callThatThrows.toString()
disposableCreation.getAReachableElement() = callThatThrows and
callThatThrows.getAReachableElement() = disposeCall and
exists(getAThrownException(callThatThrows.getARuntimeTarget()))
select disposeCall, "Dispose missed if exception is thrown by $@.", callThatThrows,
callThatThrows.toString()
9 changes: 5 additions & 4 deletions csharp/ql/src/API Abuse/FormatMissingArgument.ql
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import csharp
import semmle.code.csharp.frameworks.Format

from FormatCall format, ValidFormatString src, int used, int supplied
where src = format.getAFormatSource()
and used = src.getAnInsert()
and supplied = format.getSuppliedArguments()
and used >= supplied
where
src = format.getAFormatSource() and
used = src.getAnInsert() and
supplied = format.getSuppliedArguments() and
used >= supplied
select format, "Argument '{" + used + "}' has not been supplied to $@ format string.", src, "this"
8 changes: 5 additions & 3 deletions csharp/ql/src/API Abuse/FormatUnusedArgument.ql
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import csharp
import semmle.code.csharp.frameworks.Format

from FormatCall format, int unused, ValidFormatString src
where src = format.getAFormatSource()
and unused = format.getAnUnusedArgument(src)
select format, "The $@ ignores $@.", src, "format string", format.getSuppliedExpr(unused), "this supplied value"
where
src = format.getAFormatSource() and
unused = format.getAnUnusedArgument(src)
select format, "The $@ ignores $@.", src, "format string", format.getSuppliedExpr(unused),
"this supplied value"
15 changes: 9 additions & 6 deletions csharp/ql/src/API Abuse/InconsistentEqualsGetHashCode.ql
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,25 @@
* maintainability
* external/cwe/cwe-581
*/

import csharp
import semmle.code.csharp.frameworks.System

from Class c, Method present, string missing
where c.isSourceDeclaration() and
where
c.isSourceDeclaration() and
(
(
present = (EqualsMethod)c.getAMethod() and
present = c.getAMethod().(EqualsMethod) and
not c.getAMethod() instanceof GetHashCodeMethod and
missing = "GetHashCode()"
) or
)
or
(
present = (GetHashCodeMethod)c.getAMethod() and
present = c.getAMethod().(GetHashCodeMethod) and
not implementsEquals(c) and
missing = "Equals(object)"
)
)
select c, "Class '" + c.getName() + "' overrides $@, but not " + missing + ".",
present, present.getName()
select c, "Class '" + c.getName() + "' overrides $@, but not " + missing + ".", present,
present.getName()
30 changes: 15 additions & 15 deletions csharp/ql/src/API Abuse/IncorrectCompareToSignature.ql
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import csharp
import semmle.code.csharp.frameworks.System

predicate implementsIComparable(ValueOrRefType t, Type paramType) {
exists(ConstructedType ct |
t.getABaseType+() = ct |
exists(ConstructedType ct | t.getABaseType+() = ct |
ct = any(SystemIComparableTInterface i).getAConstructedGeneric() and
paramType = ct.getATypeArgument()
)
Expand All @@ -28,20 +27,21 @@ predicate implementsIComparable(ValueOrRefType t, Type paramType) {
}

predicate compareToMethod(Method m, Type paramType) {
m.hasName("CompareTo")
and m.fromSource()
and m.isPublic()
and m.getReturnType() instanceof IntType
and m.getNumberOfParameters() = 1
and paramType = m.getAParameter().getType()
m.hasName("CompareTo") and
m.fromSource() and
m.isPublic() and
m.getReturnType() instanceof IntType and
m.getNumberOfParameters() = 1 and
paramType = m.getAParameter().getType()
}

from Method m, RefType declaringType, Type actualParamType
where m.isSourceDeclaration()
and declaringType = m.getDeclaringType()
and compareToMethod(m, actualParamType)
and not implementsIComparable(declaringType, actualParamType)
select m, "The parameter of this 'CompareTo' method is of type $@, but $@ does not implement 'IComparable<$@>'.",
actualParamType, actualParamType.getName(),
declaringType, declaringType.getName(),
where
m.isSourceDeclaration() and
declaringType = m.getDeclaringType() and
compareToMethod(m, actualParamType) and
not implementsIComparable(declaringType, actualParamType)
select m,
"The parameter of this 'CompareTo' method is of type $@, but $@ does not implement 'IComparable<$@>'.",
actualParamType, actualParamType.getName(), declaringType, declaringType.getName(),
actualParamType, actualParamType.getName()
27 changes: 14 additions & 13 deletions csharp/ql/src/API Abuse/IncorrectEqualsSignature.ql
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,22 @@ import semmle.code.csharp.frameworks.System

class EqualsOtherMethod extends Method {
EqualsOtherMethod() {
this.hasName("Equals")
and this.getNumberOfParameters() = 1
and this.getReturnType() instanceof BoolType
and this.getDeclaringType() instanceof Class
and not this instanceof EqualsMethod
and not this instanceof IEquatableEqualsMethod
this.hasName("Equals") and
this.getNumberOfParameters() = 1 and
this.getReturnType() instanceof BoolType and
this.getDeclaringType() instanceof Class and
not this instanceof EqualsMethod and
not this instanceof IEquatableEqualsMethod
}

Type getType() {
result = this.getParameter(0).getType()
}
Type getType() { result = this.getParameter(0).getType() }
}

from EqualsOtherMethod equalsOther
where equalsOther.isSourceDeclaration()
and not implementsEquals(equalsOther.getDeclaringType())
select equalsOther, "The $@ of this 'Equals(" + equalsOther.getType().getName() + ")' method does not override 'Equals(object)'.",
equalsOther.getDeclaringType(), "declaring type"
where
equalsOther.isSourceDeclaration() and
not implementsEquals(equalsOther.getDeclaringType())
select equalsOther,
"The $@ of this 'Equals(" + equalsOther.getType().getName() +
")' method does not override 'Equals(object)'.", equalsOther.getDeclaringType(),
"declaring type"
23 changes: 12 additions & 11 deletions csharp/ql/src/API Abuse/MissingDisposeCall.ql
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ import Dispose
import semmle.code.csharp.frameworks.System

from DisposableType t, DisposableField f, Method dispose
where f.getDeclaringType() = t
and not f.isStatic()
and t.isSourceDeclaration()
and dispose = getInvokedDisposeMethod(t)
and dispose.getDeclaringType() = t
and not exists(MethodCall mc |
mc.getTarget() instanceof DisposeMethod
and mc.getQualifier() = f.getAnAccess()
and mc.getEnclosingCallable() = dispose
where
f.getDeclaringType() = t and
not f.isStatic() and
t.isSourceDeclaration() and
dispose = getInvokedDisposeMethod(t) and
dispose.getDeclaringType() = t and
not exists(MethodCall mc |
mc.getTarget() instanceof DisposeMethod and
mc.getQualifier() = f.getAnAccess() and
mc.getEnclosingCallable() = dispose
)
select dispose, "This 'Dispose()' method does not call 'Dispose()' on `IDisposable` field $@.",
f, f.getName()
select dispose, "This 'Dispose()' method does not call 'Dispose()' on `IDisposable` field $@.", f,
f.getName()
14 changes: 7 additions & 7 deletions csharp/ql/src/API Abuse/MissingDisposeMethod.ql
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import Dispose
import semmle.code.csharp.frameworks.System

from DisposableType t, DisposableField f
where f.getDeclaringType() = t
and t.isSourceDeclaration()
and not f.isStatic()
and not implementsDispose(t)
and not isAutoDisposedWebControl(f)
select t, "This type does not override 'Dispose()' but has disposable field $@.",
f, f.getName()
where
f.getDeclaringType() = t and
t.isSourceDeclaration() and
not f.isStatic() and
not implementsDispose(t) and
not isAutoDisposedWebControl(f)
select t, "This type does not override 'Dispose()' but has disposable field $@.", f, f.getName()
Loading