Check for wrapper classes

This commit is contained in:
Joe Farebrother
2025-03-06 16:21:37 +00:00
parent ecb3050780
commit c8fc56560d

View File

@@ -1,22 +1,36 @@
/** Definitions for reasoning about whether files are closed. */ /** Definitions for reasoning about whether files are closed. */
import python import python
//import semmle.python.dataflow.DataFlow import semmle.python.dataflow.new.internal.DataFlowDispatch
import semmle.python.ApiGraphs import semmle.python.ApiGraphs
abstract class FileOpen extends DataFlow::CfgNode { } abstract class FileOpen extends DataFlow::CfgNode { }
class FileOpenCall extends FileOpen { class FileOpenCall extends FileOpen {
FileOpenCall() { this = API::builtin("open").getACall() } FileOpenCall() { this = [API::builtin("open").getACall()] }
}
class FileWrapperClassCall extends FileOpen, DataFlow::CallCfgNode {
FileOpen wrapped;
FileWrapperClassCall() {
wrapped = this.getArg(_).getALocalSource() and
this.getFunction() = classTracker(_)
}
FileOpen getWrapped() { result = wrapped }
} }
// todo: type tracking to find wrapping funcs
abstract class FileClose extends DataFlow::CfgNode { } abstract class FileClose extends DataFlow::CfgNode { }
class FileCloseCall extends FileClose { class FileCloseCall extends FileClose {
FileCloseCall() { exists(DataFlow::MethodCallNode mc | mc.calls(this, "close")) } FileCloseCall() { exists(DataFlow::MethodCallNode mc | mc.calls(this, "close")) }
} }
class OsCloseCall extends FileClose {
OsCloseCall() { this = API::moduleImport("os").getMember("close").getACall().getArg(0) }
}
class WithStatement extends FileClose { class WithStatement extends FileClose {
WithStatement() { exists(With w | this.asExpr() = w.getContextExpr()) } WithStatement() { exists(With w | this.asExpr() = w.getContextExpr()) }
} }
@@ -34,6 +48,6 @@ predicate fileIsStoredInField(FileOpen fo) {
predicate fileNotAlwaysClosed(FileOpen fo) { predicate fileNotAlwaysClosed(FileOpen fo) {
not fileIsClosed(fo) and not fileIsClosed(fo) and
not fileIsReturned(fo) and not fileIsReturned(fo) and
not fileIsStoredInField(fo) not fileIsStoredInField(fo) and
// TODO: exception cases not exists(FileWrapperClassCall fwc | fo = fwc.getWrapped())
} }