Files
codeql/python/ql/src/Resources/FileNotAlwaysClosedQuery.qll
2025-03-20 11:34:33 +00:00

40 lines
1.1 KiB
Plaintext

/** Definitions for reasoning about whether files are closed. */
import python
//import semmle.python.dataflow.DataFlow
import semmle.python.ApiGraphs
abstract class FileOpen extends DataFlow::CfgNode { }
class FileOpenCall extends FileOpen {
FileOpenCall() { this = API::builtin("open").getACall() }
}
// todo: type tracking to find wrapping funcs
abstract class FileClose extends DataFlow::CfgNode { }
class FileCloseCall extends FileClose {
FileCloseCall() { exists(DataFlow::MethodCallNode mc | mc.calls(this, "close")) }
}
class WithStatement extends FileClose {
WithStatement() { exists(With w | this.asExpr() = w.getContextExpr()) }
}
predicate fileIsClosed(FileOpen fo) { exists(FileClose fc | DataFlow::localFlow(fo, fc)) }
predicate fileIsReturned(FileOpen fo) {
exists(Return ret | DataFlow::localFlow(fo, DataFlow::exprNode(ret.getValue())))
}
predicate fileIsStoredInField(FileOpen fo) {
exists(DataFlow::AttrWrite aw | DataFlow::localFlow(fo, aw.getValue()))
}
predicate fileNotAlwaysClosed(FileOpen fo) {
not fileIsClosed(fo) and
not fileIsReturned(fo) and
not fileIsStoredInField(fo)
// TODO: exception cases
}