mirror of
https://github.com/github/codeql.git
synced 2026-05-14 19:29:28 +02:00
Python: Extend ExceptionTypes API
Adds support for finding instances, and adds a `BaseException` convenience class.
This commit is contained in:
@@ -2175,12 +2175,27 @@ module ExceptionTypes {
|
||||
/** Gets a string representation of this exception type. */
|
||||
string toString() { result = this.getName() }
|
||||
|
||||
/** Gets a data-flow node that refers to an instance of this exception type. */
|
||||
DataFlow::Node getAnInstance() { none() }
|
||||
|
||||
/** Holds if this is a legal exception type (a subclass of `BaseException`). */
|
||||
predicate isLegalExceptionType() { this.getADirectSuperclass*() instanceof BaseException }
|
||||
|
||||
/**
|
||||
* Holds if this exception type is raised by `r`, either as a class reference
|
||||
* (e.g. `raise ValueError`) or as an instantiation (e.g. `raise ValueError("msg")`).
|
||||
*/
|
||||
predicate isRaisedBy(Raise r) {
|
||||
exists(Expr raised | raised = r.getRaised() |
|
||||
this.getAUse().asExpr() in [raised, raised.(Call).getFunc()]
|
||||
or
|
||||
this.getAnInstance().asExpr() = raised
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if this exception type may be raised at control flow node `r`. */
|
||||
predicate isRaisedAt(ControlFlowNode r) {
|
||||
exists(Expr raised |
|
||||
raised = r.getNode().(Raise).getRaised() and
|
||||
this.getAUse().asExpr() in [raised, raised.(Call).getFunc()]
|
||||
)
|
||||
this.isRaisedBy(r.getNode())
|
||||
or
|
||||
exists(Function callee |
|
||||
resolveCall(r, callee, _) and
|
||||
@@ -2207,7 +2222,7 @@ module ExceptionTypes {
|
||||
or
|
||||
// A bare `except:` handles everything
|
||||
not exists(handler.getNode().(ExceptStmt).getType()) and
|
||||
this.(BuiltinExceptType).getName() = "BaseException"
|
||||
this instanceof BaseException
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2237,6 +2252,8 @@ module ExceptionTypes {
|
||||
|
||||
override DataFlow::Node getAUse() { result = classTracker(cls) }
|
||||
|
||||
override DataFlow::Node getAnInstance() { result = classInstanceTracker(cls) }
|
||||
|
||||
override ExceptType getADirectSuperclass() {
|
||||
result.(UserExceptType).asClass() = getADirectSuperclass(cls)
|
||||
or
|
||||
@@ -2261,7 +2278,11 @@ module ExceptionTypes {
|
||||
|
||||
override string getName() { result = name }
|
||||
|
||||
override DataFlow::Node getAUse() { API::builtin(name).asSource().flowsTo(result) }
|
||||
override DataFlow::Node getAUse() { result = API::builtin(name).getAValueReachableFromSource() }
|
||||
|
||||
override DataFlow::Node getAnInstance() {
|
||||
result = API::builtin(name).getAnInstance().getAValueReachableFromSource()
|
||||
}
|
||||
|
||||
override ExceptType getADirectSuperclass() {
|
||||
builtinExceptionSubclass(result.(BuiltinExceptType).asBuiltinName(), name) and
|
||||
@@ -2279,6 +2300,11 @@ module ExceptionTypes {
|
||||
}
|
||||
}
|
||||
|
||||
/** The builtin `BaseException` type. */
|
||||
class BaseException extends BuiltinExceptType {
|
||||
BaseException() { name = "BaseException" }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the exception edge from `r` to `handler` is unlikely because
|
||||
* none of the exception types that `r` may raise are handled by `handler`.
|
||||
|
||||
Reference in New Issue
Block a user