mirror of
https://github.com/github/codeql.git
synced 2026-05-14 19:29:28 +02:00
Python: Port IllegalRaise.ql
Adds a convenient way to get the class name for an immutable literal (to maintain the same output format as was provided by the points-to version). I don't know if people are in the habit of writing `raise 5`, but I guess `raise "NotImplemented"` (wrong on so many levels) is not entirely impossible. No test changes.
This commit is contained in:
@@ -2134,6 +2134,23 @@ module DuckTyping {
|
||||
or
|
||||
f.getADecorator().(Name).getId() = "property"
|
||||
}
|
||||
|
||||
/** Gets the name of the builtin class of the immutable literal `lit`. */
|
||||
string getClassName(ImmutableLiteral lit) {
|
||||
lit instanceof IntegerLiteral and result = "int"
|
||||
or
|
||||
lit instanceof FloatLiteral and result = "float"
|
||||
or
|
||||
lit instanceof ImaginaryLiteral and result = "complex"
|
||||
or
|
||||
lit instanceof NegativeIntegerLiteral and result = "int"
|
||||
or
|
||||
lit instanceof StringLiteral and result = "str"
|
||||
or
|
||||
lit instanceof BooleanLiteral and result = "bool"
|
||||
or
|
||||
lit instanceof None and result = "NoneType"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,15 +12,48 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
import Raising
|
||||
import Exceptions.NotImplemented
|
||||
private import LegacyPointsTo
|
||||
import semmle.python.dataflow.new.internal.DataFlowDispatch
|
||||
import semmle.python.ApiGraphs
|
||||
private import ExceptionTypes
|
||||
|
||||
from Raise r, ClassValue t
|
||||
/**
|
||||
* Holds if `r` raises an instance of a builtin non-exception class named `name`.
|
||||
*/
|
||||
private predicate raisesNonExceptionBuiltin(Raise r, string name) {
|
||||
exists(Expr raised | raised = r.getRaised() |
|
||||
API::builtin(name).getAValueReachableFromSource().asExpr() = raised
|
||||
or
|
||||
API::builtin(name).getAValueReachableFromSource().asExpr() = raised.(Call).getFunc() and
|
||||
// Exclude `type` since `type(x)` returns the class of `x`, not a `type` instance
|
||||
not name = "type"
|
||||
) and
|
||||
not builtinException(name)
|
||||
}
|
||||
|
||||
from Raise r, string msg
|
||||
where
|
||||
type_or_typeof(r, t, _) and
|
||||
not t.isLegalExceptionType() and
|
||||
not t.failedInference(_) and
|
||||
not use_of_not_implemented_in_raise(r, _)
|
||||
select r,
|
||||
"Illegal class '" + t.getName() + "' raised; will result in a TypeError being raised instead."
|
||||
not raisesNonExceptionBuiltin(r, "NotImplemented") and
|
||||
(
|
||||
exists(ExceptType t |
|
||||
t.isRaisedBy(r) and
|
||||
not t.isLegalExceptionType() and
|
||||
not t.getName() = "None" and
|
||||
msg =
|
||||
"Illegal class '" + t.getName() +
|
||||
"' raised; will result in a TypeError being raised instead."
|
||||
)
|
||||
or
|
||||
exists(ImmutableLiteral lit | lit = r.getRaised() |
|
||||
msg =
|
||||
"Illegal class '" + DuckTyping::getClassName(lit) +
|
||||
"' raised; will result in a TypeError being raised instead."
|
||||
)
|
||||
or
|
||||
exists(string name |
|
||||
raisesNonExceptionBuiltin(r, name) and
|
||||
not r.getRaised() instanceof ImmutableLiteral and
|
||||
not name = "None" and
|
||||
msg = "Illegal class '" + name + "' raised; will result in a TypeError being raised instead."
|
||||
)
|
||||
)
|
||||
select r, msg
|
||||
|
||||
Reference in New Issue
Block a user