mirror of
https://github.com/github/codeql.git
synced 2025-12-20 10:46:30 +01:00
Python: restrict to caught exceptions
also modernise code
This commit is contained in:
@@ -1661,138 +1661,28 @@ private module Stdlib {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// traceback
|
// traceback
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Gets a reference to the `traceback` module. */
|
|
||||||
API::Node traceback() { result = API::moduleImport("traceback") }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a reference to the attribute `attr_name` of the `traceback` module.
|
|
||||||
*/
|
|
||||||
private API::Node traceback_attr(string attr_name) { result = traceback().getMember(attr_name) }
|
|
||||||
|
|
||||||
/** Provides models for the `traceback` module. */
|
/** Provides models for the `traceback` module. */
|
||||||
module traceback {
|
module traceback {
|
||||||
private class TracebackFunctionCall extends ErrorInfoSource::Range, DataFlow::CfgNode {
|
private class TracebackFunctionCall extends ErrorInfoSource::Range, DataFlow::CallCfgNode {
|
||||||
override CallNode node;
|
|
||||||
|
|
||||||
TracebackFunctionCall() {
|
TracebackFunctionCall() {
|
||||||
node.getFunction() =
|
this =
|
||||||
traceback_attr([
|
API::moduleImport("traceback")
|
||||||
"extract_tb", "extract_stack", "format_list", "format_exception_only",
|
.getMember([
|
||||||
"format_exception", "format_exc", "format_tb", "format_stack"
|
"extract_tb", "extract_stack", "format_list", "format_exception_only",
|
||||||
]).getAUse().asCfgNode()
|
"format_exception", "format_exc", "format_tb", "format_stack"
|
||||||
|
])
|
||||||
|
.getACall()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private class CaughtException extends ExceptionSource::Range {
|
||||||
* Provides models for the `Stdlib.BaseException` class
|
CaughtException() { this.asExpr() = any(ExceptStmt s).getName() }
|
||||||
*
|
|
||||||
* See https://docs.python.org/3/library/exceptions.html#BaseException.
|
|
||||||
*/
|
|
||||||
module BaseException {
|
|
||||||
/** Gets a reference to the `Stdlib.BaseException` class. */
|
|
||||||
private DataFlow::Node classRef(DataFlow::TypeTracker t) {
|
|
||||||
t.start() and
|
|
||||||
result.asExpr().(Name).getId() = "BaseException"
|
|
||||||
or
|
|
||||||
exists(DataFlow::TypeTracker t2 | result = classRef(t2).track(t2, t))
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets a reference to the `Stdlib.BaseException` class. */
|
|
||||||
DataFlow::Node classRef() { result = classRef(DataFlow::TypeTracker::end()) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A source of an instance of `Stdlib.BaseException`.
|
|
||||||
*
|
|
||||||
* This can include instantiation of the class, return value from function
|
|
||||||
* calls, or a special parameter that will be set when functions are call by external
|
|
||||||
* library.
|
|
||||||
*
|
|
||||||
* Use `BaseException::instance()` predicate to get references to instances of `Stdlib.BaseException`.
|
|
||||||
*/
|
|
||||||
abstract class InstanceSource extends DataFlow::Node { }
|
|
||||||
|
|
||||||
/** A direct instantiation of `Stdlib.BaseException`. */
|
|
||||||
private class ClassInstantiation extends InstanceSource, DataFlow::CfgNode {
|
|
||||||
override CallNode node;
|
|
||||||
|
|
||||||
ClassInstantiation() { node.getFunction() = classRef().asCfgNode() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets a reference to an instance of `Stdlib.BaseException`. */
|
|
||||||
private DataFlow::Node instance(DataFlow::TypeTracker t) {
|
|
||||||
t.start() and
|
|
||||||
result instanceof InstanceSource
|
|
||||||
or
|
|
||||||
exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t))
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets a reference to an instance of `Stdlib.BaseException`. */
|
|
||||||
DataFlow::Node instance() { result = instance(DataFlow::TypeTracker::end()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides models for the `BaseException` class and subclasses.
|
|
||||||
*/
|
|
||||||
private module Exception {
|
|
||||||
/** Gets a reference to the `BaseHTTPRequestHandler` class or any subclass. */
|
|
||||||
private DataFlow::Node subclassRef(DataFlow::TypeTracker t) {
|
|
||||||
t.start() and
|
|
||||||
result = BaseException::classRef()
|
|
||||||
or
|
|
||||||
// subclasses in project code
|
|
||||||
result.asExpr().(ClassExpr).getABase() = subclassRef(t.continue()).asExpr()
|
|
||||||
or
|
|
||||||
exists(DataFlow::TypeTracker t2 | result = subclassRef(t2).track(t2, t))
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets a reference to the `BaseException` class or any subclass. */
|
|
||||||
DataFlow::Node subclassRef() { result = subclassRef(DataFlow::TypeTracker::end()) }
|
|
||||||
|
|
||||||
/** A HTTPRequestHandler class definition (most likely in project code). */
|
|
||||||
class ExceptionClassDef extends Class {
|
|
||||||
ExceptionClassDef() { this.getParent() = subclassRef().asExpr() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A source of instances of the `BaseException` class or any subclass, extend this class to model new instances.
|
|
||||||
*
|
|
||||||
* This can include instantiations of the class, return values from function
|
|
||||||
* calls, or a special parameter that will be set when functions are called by an external
|
|
||||||
* library.
|
|
||||||
*
|
|
||||||
* Use the predicate `classname::instance()` to get references to instances of the `Exception` class or any subclass.
|
|
||||||
*/
|
|
||||||
abstract class InstanceSource extends DataFlow::Node { }
|
|
||||||
|
|
||||||
/** The `self` parameter in a method on the `BaseException` class or any subclass. */
|
|
||||||
private class SelfParam extends InstanceSource, DataFlow::ParameterNode {
|
|
||||||
SelfParam() { exists(ExceptionClassDef cls | cls.getAMethod().getArg(0) = this.getParameter()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets a reference to an instance of the `BaseException` class or any subclass. */
|
|
||||||
private DataFlow::Node instance(DataFlow::TypeTracker t) {
|
|
||||||
t.start() and
|
|
||||||
result instanceof InstanceSource
|
|
||||||
or
|
|
||||||
exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t))
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets a reference to an instance of the `BaseException` class or any subclass. */
|
|
||||||
DataFlow::Node instance() { result = instance(DataFlow::TypeTracker::end()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Exception extends ExceptionSource::Range {
|
|
||||||
Exception() {
|
|
||||||
this = Exception::instance()
|
|
||||||
or
|
|
||||||
this.asExpr() = any(ExceptStmt s).getName()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A call to `sys.exc_info` */
|
/** A call to `sys.exc_info` */
|
||||||
private class SysExcInfoCall extends ErrorInfoSource::Range, DataFlow::CfgNode {
|
private class SysExcInfoCall extends ErrorInfoSource::Range, DataFlow::CallCfgNode {
|
||||||
SysExcInfoCall() { this = API::moduleImport("sys").getMember("exc_info").getACall() }
|
SysExcInfoCall() { this = API::moduleImport("sys").getMember("exc_info").getACall() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user