mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Python: Remove points-to dependency from parts of SSA
For whatever reason, the CFG node for exceptions and exception groups was placed with the points-to code. (Probably because a lot of the predicates depended on points-to.) However, as it turned out, two of the SSA modules only depended on non-points-to properties of these nodes, and so it was fairly straightforward to remove the imports of `LegacyPointsTo` for those modules. In the process, I moved the aforementioned CFG node types into `Flow.qll`, and changed the classes in the `Exceptions` module to the `...WithPointsTo` form that we introduced elsewhere.
This commit is contained in:
@@ -883,6 +883,58 @@ class StarredNode extends ControlFlowNode {
|
|||||||
ControlFlowNode getValue() { toAst(result) = toAst(this).(Starred).getValue() }
|
ControlFlowNode getValue() { toAst(result) = toAst(this).(Starred).getValue() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The ControlFlowNode for an 'except' statement. */
|
||||||
|
class ExceptFlowNode extends ControlFlowNode {
|
||||||
|
ExceptFlowNode() { this.getNode() instanceof ExceptStmt }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type handled by this exception handler.
|
||||||
|
* `ExceptionType` in `except ExceptionType as e:`
|
||||||
|
*/
|
||||||
|
ControlFlowNode getType() {
|
||||||
|
exists(ExceptStmt ex |
|
||||||
|
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
||||||
|
ex = this.getNode() and
|
||||||
|
result = ex.getType().getAFlowNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name assigned to the handled exception, if any.
|
||||||
|
* `e` in `except ExceptionType as e:`
|
||||||
|
*/
|
||||||
|
ControlFlowNode getName() {
|
||||||
|
exists(ExceptStmt ex |
|
||||||
|
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
||||||
|
ex = this.getNode() and
|
||||||
|
result = ex.getName().getAFlowNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The ControlFlowNode for an 'except*' statement. */
|
||||||
|
class ExceptGroupFlowNode extends ControlFlowNode {
|
||||||
|
ExceptGroupFlowNode() { this.getNode() instanceof ExceptGroupStmt }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type handled by this exception handler.
|
||||||
|
* `ExceptionType` in `except* ExceptionType as e:`
|
||||||
|
*/
|
||||||
|
ControlFlowNode getType() {
|
||||||
|
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
||||||
|
result = this.getNode().(ExceptGroupStmt).getType().getAFlowNode()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name assigned to the handled exception, if any.
|
||||||
|
* `e` in `except* ExceptionType as e:`
|
||||||
|
*/
|
||||||
|
ControlFlowNode getName() {
|
||||||
|
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
||||||
|
result = this.getNode().(ExceptGroupStmt).getName().getAFlowNode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private module Scopes {
|
private module Scopes {
|
||||||
private predicate fast_local(NameNode n) {
|
private predicate fast_local(NameNode n) {
|
||||||
exists(FastLocalVariable v |
|
exists(FastLocalVariable v |
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import python
|
|||||||
private import SsaCompute
|
private import SsaCompute
|
||||||
import semmle.python.essa.Definitions
|
import semmle.python.essa.Definitions
|
||||||
private import semmle.python.internal.CachedStages
|
private import semmle.python.internal.CachedStages
|
||||||
private import LegacyPointsTo
|
|
||||||
private import semmle.python.essa.SsaDefinitions
|
private import semmle.python.essa.SsaDefinitions
|
||||||
|
|
||||||
/** An (enhanced) SSA variable derived from `SsaSourceVariable`. */
|
/** An (enhanced) SSA variable derived from `SsaSourceVariable`. */
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
import python
|
import python
|
||||||
private import semmle.python.internal.CachedStages
|
private import semmle.python.internal.CachedStages
|
||||||
private import LegacyPointsTo
|
|
||||||
|
|
||||||
/** Hold if `expr` is a test (a branch) and `use` is within that test */
|
/** Hold if `expr` is a test (a branch) and `use` is within that test */
|
||||||
predicate test_contains(ControlFlowNode expr, ControlFlowNode use) {
|
predicate test_contains(ControlFlowNode expr, ControlFlowNode use) {
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ class RaisingNode extends ControlFlowNode {
|
|||||||
or
|
or
|
||||||
this.getNode() instanceof Print and result = theIOErrorType()
|
this.getNode() instanceof Print and result = theIOErrorType()
|
||||||
or
|
or
|
||||||
exists(ExceptFlowNode except |
|
exists(ExceptFlowNodeWithPointsTo except |
|
||||||
except = this.getAnExceptionalSuccessor() and
|
except = this.getAnExceptionalSuccessor() and
|
||||||
except.handles_objectapi(result) and
|
except.handles_objectapi(result) and
|
||||||
result = this.innateException_objectapi()
|
result = this.innateException_objectapi()
|
||||||
@@ -107,7 +107,7 @@ class RaisingNode extends ControlFlowNode {
|
|||||||
or
|
or
|
||||||
this.getNode() instanceof Print and result = ClassValue::ioError()
|
this.getNode() instanceof Print and result = ClassValue::ioError()
|
||||||
or
|
or
|
||||||
exists(ExceptFlowNode except |
|
exists(ExceptFlowNodeWithPointsTo except |
|
||||||
except = this.getAnExceptionalSuccessor() and
|
except = this.getAnExceptionalSuccessor() and
|
||||||
except.handles(result) and
|
except.handles(result) and
|
||||||
result = this.innateException()
|
result = this.innateException()
|
||||||
@@ -200,8 +200,8 @@ class RaisingNode extends ControlFlowNode {
|
|||||||
succ = this.getAnExceptionalSuccessor() and
|
succ = this.getAnExceptionalSuccessor() and
|
||||||
(
|
(
|
||||||
/* An 'except' that handles raised and there is no more previous handler */
|
/* An 'except' that handles raised and there is no more previous handler */
|
||||||
succ.(ExceptFlowNode).handles_objectapi(raised) and
|
succ.(ExceptFlowNodeWithPointsTo).handles_objectapi(raised) and
|
||||||
not exists(ExceptFlowNode other, StmtList s, int i, int j |
|
not exists(ExceptFlowNodeWithPointsTo other, StmtList s, int i, int j |
|
||||||
not other = succ and
|
not other = succ and
|
||||||
other.handles_objectapi(raised) and
|
other.handles_objectapi(raised) and
|
||||||
s.getItem(i) = succ.getNode() and
|
s.getItem(i) = succ.getNode() and
|
||||||
@@ -211,7 +211,7 @@ class RaisingNode extends ControlFlowNode {
|
|||||||
)
|
)
|
||||||
or
|
or
|
||||||
/* Any successor that is not an 'except', provided that 'raised' is not handled by a different successor. */
|
/* Any successor that is not an 'except', provided that 'raised' is not handled by a different successor. */
|
||||||
not this.getAnExceptionalSuccessor().(ExceptFlowNode).handles_objectapi(raised) and
|
not this.getAnExceptionalSuccessor().(ExceptFlowNodeWithPointsTo).handles_objectapi(raised) and
|
||||||
not succ instanceof ExceptFlowNode
|
not succ instanceof ExceptFlowNode
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -223,8 +223,8 @@ class RaisingNode extends ControlFlowNode {
|
|||||||
succ = this.getAnExceptionalSuccessor() and
|
succ = this.getAnExceptionalSuccessor() and
|
||||||
(
|
(
|
||||||
/* An 'except' that handles raised and there is no more previous handler */
|
/* An 'except' that handles raised and there is no more previous handler */
|
||||||
succ.(ExceptFlowNode).handles(raised) and
|
succ.(ExceptFlowNodeWithPointsTo).handles(raised) and
|
||||||
not exists(ExceptFlowNode other, StmtList s, int i, int j |
|
not exists(ExceptFlowNodeWithPointsTo other, StmtList s, int i, int j |
|
||||||
not other = succ and
|
not other = succ and
|
||||||
other.handles(raised) and
|
other.handles(raised) and
|
||||||
s.getItem(i) = succ.getNode() and
|
s.getItem(i) = succ.getNode() and
|
||||||
@@ -234,7 +234,7 @@ class RaisingNode extends ControlFlowNode {
|
|||||||
)
|
)
|
||||||
or
|
or
|
||||||
/* Any successor that is not an 'except', provided that 'raised' is not handled by a different successor. */
|
/* Any successor that is not an 'except', provided that 'raised' is not handled by a different successor. */
|
||||||
not this.getAnExceptionalSuccessor().(ExceptFlowNode).handles(raised) and
|
not this.getAnExceptionalSuccessor().(ExceptFlowNodeWithPointsTo).handles(raised) and
|
||||||
not succ instanceof ExceptFlowNode
|
not succ instanceof ExceptFlowNode
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -248,7 +248,7 @@ class RaisingNode extends ControlFlowNode {
|
|||||||
raised.isLegalExceptionType() and
|
raised.isLegalExceptionType() and
|
||||||
raised = this.getARaisedType_objectapi() and
|
raised = this.getARaisedType_objectapi() and
|
||||||
this.isExceptionalExit(s) and
|
this.isExceptionalExit(s) and
|
||||||
not this.getAnExceptionalSuccessor().(ExceptFlowNode).handles_objectapi(raised)
|
not this.getAnExceptionalSuccessor().(ExceptFlowNodeWithPointsTo).handles_objectapi(raised)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -260,7 +260,7 @@ class RaisingNode extends ControlFlowNode {
|
|||||||
raised.isLegalExceptionType() and
|
raised.isLegalExceptionType() and
|
||||||
raised = this.getARaisedType() and
|
raised = this.getARaisedType() and
|
||||||
this.isExceptionalExit(s) and
|
this.isExceptionalExit(s) and
|
||||||
not this.getAnExceptionalSuccessor().(ExceptFlowNode).handles(raised)
|
not this.getAnExceptionalSuccessor().(ExceptFlowNodeWithPointsTo).handles(raised)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,36 +368,9 @@ predicate scope_raises_unknown(Scope s) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The ControlFlowNode for an 'except' statement. */
|
class ExceptFlowNodeWithPointsTo extends ExceptFlowNode {
|
||||||
class ExceptFlowNode extends ControlFlowNode {
|
|
||||||
ExceptFlowNode() { this.getNode() instanceof ExceptStmt }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the type handled by this exception handler.
|
|
||||||
* `ExceptionType` in `except ExceptionType as e:`
|
|
||||||
*/
|
|
||||||
ControlFlowNodeWithPointsTo getType() {
|
|
||||||
exists(ExceptStmt ex |
|
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
|
||||||
ex = this.getNode() and
|
|
||||||
result = ex.getType().getAFlowNode()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the name assigned to the handled exception, if any.
|
|
||||||
* `e` in `except ExceptionType as e:`
|
|
||||||
*/
|
|
||||||
ControlFlowNode getName() {
|
|
||||||
exists(ExceptStmt ex |
|
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
|
||||||
ex = this.getNode() and
|
|
||||||
result = ex.getName().getAFlowNode()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate handledObject_objectapi(Object obj, ClassObject cls, ControlFlowNode origin) {
|
private predicate handledObject_objectapi(Object obj, ClassObject cls, ControlFlowNode origin) {
|
||||||
this.getType().refersTo(obj, cls, origin)
|
this.getType().(ControlFlowNodeWithPointsTo).refersTo(obj, cls, origin)
|
||||||
or
|
or
|
||||||
exists(Object tup | this.handledObject_objectapi(tup, theTupleType(), _) |
|
exists(Object tup | this.handledObject_objectapi(tup, theTupleType(), _) |
|
||||||
element_from_tuple_objectapi(tup).refersTo(obj, cls, origin)
|
element_from_tuple_objectapi(tup).refersTo(obj, cls, origin)
|
||||||
@@ -407,7 +380,7 @@ class ExceptFlowNode extends ControlFlowNode {
|
|||||||
private predicate handledObject(Value val, ClassValue cls, ControlFlowNode origin) {
|
private predicate handledObject(Value val, ClassValue cls, ControlFlowNode origin) {
|
||||||
val.getClass() = cls and
|
val.getClass() = cls and
|
||||||
(
|
(
|
||||||
this.getType().pointsTo(val, origin)
|
this.getType().(ControlFlowNodeWithPointsTo).pointsTo(val, origin)
|
||||||
or
|
or
|
||||||
exists(TupleValue tup | this.handledObject(tup, ClassValue::tuple(), _) |
|
exists(TupleValue tup | this.handledObject(tup, ClassValue::tuple(), _) |
|
||||||
val = tup.getItem(_) and origin = val.getOrigin()
|
val = tup.getItem(_) and origin = val.getOrigin()
|
||||||
@@ -452,29 +425,6 @@ class ExceptFlowNode extends ControlFlowNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The ControlFlowNode for an 'except*' statement. */
|
|
||||||
class ExceptGroupFlowNode extends ControlFlowNode {
|
|
||||||
ExceptGroupFlowNode() { this.getNode() instanceof ExceptGroupStmt }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the type handled by this exception handler.
|
|
||||||
* `ExceptionType` in `except* ExceptionType as e:`
|
|
||||||
*/
|
|
||||||
ControlFlowNode getType() {
|
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
|
||||||
result = this.getNode().(ExceptGroupStmt).getType().getAFlowNode()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the name assigned to the handled exception, if any.
|
|
||||||
* `e` in `except* ExceptionType as e:`
|
|
||||||
*/
|
|
||||||
ControlFlowNode getName() {
|
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
|
||||||
result = this.getNode().(ExceptGroupStmt).getName().getAFlowNode()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ControlFlowNodeWithPointsTo element_from_tuple_objectapi(Object tuple) {
|
private ControlFlowNodeWithPointsTo element_from_tuple_objectapi(Object tuple) {
|
||||||
exists(Tuple t | t = tuple.getOrigin() and result = t.getAnElt().getAFlowNode())
|
exists(Tuple t | t = tuple.getOrigin() and result = t.getAnElt().getAFlowNode())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
import python
|
import python
|
||||||
private import LegacyPointsTo
|
private import LegacyPointsTo
|
||||||
|
|
||||||
from ExceptFlowNode ex, Value t, ClassValue c, ControlFlowNode origin, string what
|
from ExceptFlowNodeWithPointsTo ex, Value t, ClassValue c, ControlFlowNode origin, string what
|
||||||
where
|
where
|
||||||
ex.handledException(t, c, origin) and
|
ex.handledException(t, c, origin) and
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import python
|
import python
|
||||||
private import LegacyPointsTo
|
private import LegacyPointsTo
|
||||||
|
|
||||||
from ExceptFlowNode ex, Value val
|
from ExceptFlowNodeWithPointsTo ex, Value val
|
||||||
where ex.handledException(val, _, _)
|
where ex.handledException(val, _, _)
|
||||||
select ex.getLocation().getStartLine(), ex.toString(), val.toString()
|
select ex.getLocation().getStartLine(), ex.toString(), val.toString()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import python
|
import python
|
||||||
private import LegacyPointsTo
|
private import LegacyPointsTo
|
||||||
|
|
||||||
from ExceptFlowNode ex, Value val
|
from ExceptFlowNodeWithPointsTo ex, Value val
|
||||||
where ex.handledException(val, _, _)
|
where ex.handledException(val, _, _)
|
||||||
select ex.getLocation().getStartLine(), ex.toString(), val.toString()
|
select ex.getLocation().getStartLine(), ex.toString(), val.toString()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import python
|
import python
|
||||||
private import LegacyPointsTo
|
private import LegacyPointsTo
|
||||||
|
|
||||||
from ExceptFlowNode ex, Value val
|
from ExceptFlowNodeWithPointsTo ex, Value val
|
||||||
where ex.handledException(val, _, _)
|
where ex.handledException(val, _, _)
|
||||||
select ex.getLocation().getStartLine(), ex.toString(), val.toString()
|
select ex.getLocation().getStartLine(), ex.toString(), val.toString()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import python
|
import python
|
||||||
private import LegacyPointsTo
|
private import LegacyPointsTo
|
||||||
|
|
||||||
from ExceptFlowNode n, ClassObject cls
|
from ExceptFlowNodeWithPointsTo n, ClassObject cls
|
||||||
where n.handles_objectapi(cls)
|
where n.handles_objectapi(cls)
|
||||||
select n.getLocation().getStartLine(), cls.toString()
|
select n.getLocation().getStartLine(), cls.toString()
|
||||||
|
|||||||
Reference in New Issue
Block a user