mirror of
https://github.com/github/codeql.git
synced 2026-05-01 11:45:14 +02:00
Merge pull request #2978 from BekaValentine/python-objectapi-to-valueapi-illegalexceptionhandlertype
Python: ObjectAPI to ValueAPI: IllegalExceptionHandlerType
This commit is contained in:
@@ -13,18 +13,18 @@
|
||||
|
||||
import python
|
||||
|
||||
from ExceptFlowNode ex, Object t, ClassObject c, ControlFlowNode origin, string what
|
||||
where ex.handledException(t, c, origin) and
|
||||
(
|
||||
exists(ClassObject x | x = t |
|
||||
not x.isLegalExceptionType() and
|
||||
not x.failedInference() and
|
||||
what = "class '" + x.getName() + "'"
|
||||
)
|
||||
or
|
||||
not t instanceof ClassObject and
|
||||
what = "instance of '" + c.getName() + "'"
|
||||
)
|
||||
|
||||
select ex.getNode(), "Non-exception $@ in exception handler which will never match raised exception.", origin, what
|
||||
|
||||
from ExceptFlowNode ex, Value t, ClassValue c, ControlFlowNode origin, string what
|
||||
where
|
||||
ex.handledException(t, c, origin) and
|
||||
(
|
||||
exists(ClassValue x | x = t |
|
||||
not x.isLegalExceptionType() and
|
||||
not x.failedInference(_) and
|
||||
what = "class '" + x.getName() + "'"
|
||||
)
|
||||
or
|
||||
not t instanceof ClassValue and
|
||||
what = "instance of '" + c.getName() + "'"
|
||||
)
|
||||
select ex.getNode(),
|
||||
"Non-exception $@ in exception handler which will never match raised exception.", origin, what
|
||||
|
||||
@@ -44,6 +44,12 @@ class Value extends TObject {
|
||||
PointsToInternal::pointsTo(result, _, this, _)
|
||||
}
|
||||
|
||||
/** Gets the origin CFG node for this value. */
|
||||
ControlFlowNode getOrigin() {
|
||||
result = this.(ObjectInternal).getOrigin()
|
||||
}
|
||||
|
||||
|
||||
/** Gets the class of this object.
|
||||
* Strictly, the `Value` representing the class of the objects
|
||||
* represented by this Value.
|
||||
|
||||
@@ -260,35 +260,58 @@ class ExceptFlowNode extends ControlFlowNode {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate handledObject(Object obj, ClassObject cls, ControlFlowNode origin) {
|
||||
private predicate handledObject_objectapi(Object obj, ClassObject cls, ControlFlowNode origin) {
|
||||
this.getType().refersTo(obj, cls, origin)
|
||||
or
|
||||
exists(Object tup |
|
||||
this.handledObject(tup, theTupleType(), _) |
|
||||
element_from_tuple(tup).refersTo(obj, cls, origin)
|
||||
this.handledObject_objectapi(tup, theTupleType(), _) |
|
||||
element_from_tuple_objectapi(tup).refersTo(obj, cls, origin)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate handledObject(Value val, ClassValue cls, ControlFlowNode origin) {
|
||||
val.getClass() = cls and
|
||||
(
|
||||
this.getType().pointsTo(val, origin)
|
||||
or
|
||||
exists(TupleValue tup |
|
||||
this.handledObject(tup, ClassValue::tuple(), _) |
|
||||
val = tup.getItem(_) and origin = val.getOrigin()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the inferred type(s) that are handled by this node, splitting tuples if possible. */
|
||||
pragma [noinline]
|
||||
predicate handledException(Object obj, ClassObject cls, ControlFlowNode origin) {
|
||||
this.handledObject(obj, cls, origin) and not cls = theTupleType()
|
||||
predicate handledException_objectapi(Object obj, ClassObject cls, ControlFlowNode origin) {
|
||||
this.handledObject_objectapi(obj, cls, origin) and not cls = theTupleType()
|
||||
or
|
||||
not exists(this.getNode().(ExceptStmt).getType()) and obj = theBaseExceptionType() and cls = theTypeType() and
|
||||
origin = this
|
||||
}
|
||||
|
||||
/** Gets the inferred type(s) that are handled by this node, splitting tuples if possible. */
|
||||
pragma [noinline]
|
||||
predicate handledException(Value val, ClassValue cls, ControlFlowNode origin) {
|
||||
this.handledObject(val, cls, origin) and not cls = ClassValue::tuple()
|
||||
or
|
||||
not exists(this.getNode().(ExceptStmt).getType()) and val = ClassValue::baseException() and cls = ClassValue::type() and
|
||||
origin = this
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Whether this `except` handles `cls` */
|
||||
predicate handles(ClassObject cls) {
|
||||
exists(ClassObject handled |
|
||||
this.handledException(handled, _, _) |
|
||||
this.handledException_objectapi(handled, _, _) |
|
||||
cls.getAnImproperSuperType() = handled
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ControlFlowNode element_from_tuple(Object tuple) {
|
||||
private ControlFlowNode element_from_tuple_objectapi(Object tuple) {
|
||||
exists(Tuple t |
|
||||
t = tuple.getOrigin() and result = t.getAnElt().getAFlowNode()
|
||||
)
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
import python
|
||||
|
||||
from ExceptFlowNode ex, Object obj
|
||||
where ex.handledException(obj, _, _)
|
||||
where ex.handledException_objectapi(obj, _, _)
|
||||
select ex.getLocation().getStartLine(), ex.toString(), obj.toString()
|
||||
@@ -2,5 +2,5 @@
|
||||
import python
|
||||
|
||||
from ExceptFlowNode ex, Object obj
|
||||
where ex.handledException(obj, _, _)
|
||||
where ex.handledException_objectapi(obj, _, _)
|
||||
select ex.getLocation().getStartLine(), ex.toString(), obj.toString()
|
||||
@@ -1,5 +1,5 @@
|
||||
import python
|
||||
|
||||
from ExceptFlowNode ex, Object t
|
||||
where ex.handledException(t, _, _)
|
||||
where ex.handledException_objectapi(t, _, _)
|
||||
select ex.getLocation().getStartLine(), ex.toString(), t.toString()
|
||||
Reference in New Issue
Block a user