Files
codeql/csharp/ql/src/API Abuse/Dispose.qll

64 lines
1.9 KiB
Plaintext

import csharp
private import DataFlow
private import semmle.code.csharp.frameworks.System
private import semmle.code.csharp.frameworks.system.web.UI
class DisposableType extends RefType {
DisposableType() { this.getABaseType+() instanceof SystemIDisposableInterface }
}
class DisposableField extends Field {
DisposableField() { this.getType() instanceof DisposableType }
}
class WebControl extends RefType {
WebControl() { this.getBaseClass*() instanceof SystemWebUIControlClass }
}
class WebPage extends RefType {
WebPage() { this.getBaseClass*() instanceof SystemWebUIPageClass }
}
/**
* Holds if `f` is an auto-disposed web control.
*
* Web controls that are either child controls or controls on a page
* are auto disposed: `System.Web.UI.Control` defines `UnloadRecursive()`
* which invokes `Dispose()` recursively on all nested controls;
* `System.Web.UI.Page` defines `ProcessRequestCleanup()` which invokes
* `UnloadRecursive()`.
*/
predicate isAutoDisposedWebControl(Field f) {
f.getType() instanceof WebControl and
f.getDeclaringType() =
any(RefType t |
t instanceof WebControl or
t instanceof WebPage
)
}
/**
* An object creation that creates an `IDisposable` instance into the local scope.
*/
class LocalScopeDisposableCreation extends Call {
LocalScopeDisposableCreation() {
exists(Type t |
t = this.getType() and
// Type extends IDisposable
t instanceof DisposableType and
// Within function, not field or instance initializer
exists(this.getEnclosingCallable())
|
// Either an ordinary object creation
this instanceof ObjectCreation
or
// Or a creation using a factory method
exists(Method create | this.getTarget() = create |
create.hasName("Create") and
create.isStatic() and
create.getDeclaringType().getUnboundDeclaration() = t.getUnboundDeclaration()
)
)
}
}