Merge pull request #2978 from BekaValentine/python-objectapi-to-valueapi-illegalexceptionhandlertype

Python: ObjectAPI to ValueAPI: IllegalExceptionHandlerType
This commit is contained in:
Taus
2020-03-17 17:56:34 +01:00
committed by GitHub
6 changed files with 54 additions and 25 deletions

View File

@@ -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

View File

@@ -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.

View File

@@ -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()
)

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()