mirror of
https://github.com/github/codeql.git
synced 2026-03-06 15:49:08 +01:00
Python: Improve usefulness of RemoteFlowSourcesReach meta query
Before, results from `dca` would look something like
## + py/meta/alerts/remote-flow-sources-reach
- django/django@c2250cf_cb8f: tests/messages_tests/urls.py:38:16:38:48
reachable with taint-tracking from RemoteFlowSource
- django/django@c2250cf_cb8f: tests/messages_tests/urls.py:38:9:38:12
reachable with taint-tracking from RemoteFlowSource
now it should make it easier to spot _what_ it is that actually changed,
since we pretty-print the node.
This commit is contained in:
@@ -14,6 +14,7 @@ private import semmle.python.dataflow.new.DataFlow
|
||||
private import semmle.python.dataflow.new.TaintTracking
|
||||
private import semmle.python.dataflow.new.RemoteFlowSources
|
||||
private import meta.MetaMetrics
|
||||
private import semmle.python.dataflow.new.internal.PrintNode
|
||||
|
||||
class RemoteFlowSourceReach extends TaintTracking::Configuration {
|
||||
RemoteFlowSourceReach() { this = "RemoteFlowSourceReach" }
|
||||
@@ -43,4 +44,4 @@ class RemoteFlowSourceReach extends TaintTracking::Configuration {
|
||||
|
||||
from RemoteFlowSourceReach cfg, DataFlow::Node reachable
|
||||
where cfg.hasFlow(_, reachable)
|
||||
select reachable, "reachable with taint-tracking from RemoteFlowSource"
|
||||
select reachable, prettyNode(reachable)
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Provides helper predicates for pretty-printing `DataFlow::Node`s.
|
||||
*
|
||||
* Since these have not been performance optimized, please only use them for
|
||||
* debug-queries or in tests.
|
||||
*/
|
||||
|
||||
private import python
|
||||
private import semmle.python.dataflow.new.DataFlow
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Gets the pretty-printed version of the Expr `e`.
|
||||
*/
|
||||
string prettyExpr(Expr e) {
|
||||
not e instanceof Num and
|
||||
not e instanceof StrConst and
|
||||
not e instanceof Subscript and
|
||||
not e instanceof Call and
|
||||
not e instanceof Attribute and
|
||||
result = e.toString()
|
||||
or
|
||||
result = e.(Num).getN()
|
||||
or
|
||||
result =
|
||||
e.(StrConst).getPrefix() + e.(StrConst).getText() +
|
||||
e.(StrConst).getPrefix().regexpReplaceAll("[a-zA-Z]+", "")
|
||||
or
|
||||
result = prettyExpr(e.(Subscript).getObject()) + "[" + prettyExpr(e.(Subscript).getIndex()) + "]"
|
||||
or
|
||||
(
|
||||
if exists(e.(Call).getAnArg()) or exists(e.(Call).getANamedArg())
|
||||
then result = prettyExpr(e.(Call).getFunc()) + "(..)"
|
||||
else result = prettyExpr(e.(Call).getFunc()) + "()"
|
||||
)
|
||||
or
|
||||
result = prettyExpr(e.(Attribute).getObject()) + "." + e.(Attribute).getName()
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Gets the pretty-printed version of the DataFlow::Node `node`
|
||||
*/
|
||||
bindingset[node]
|
||||
string prettyNode(DataFlow::Node node) {
|
||||
if exists(node.asExpr()) then result = prettyExpr(node.asExpr()) else result = node.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Gets the pretty-printed version of the DataFlow::Node `node`, that is suitable for use
|
||||
* with `TestUtilities.InlineExpectationsTest` (that is, no spaces unless required).
|
||||
*/
|
||||
bindingset[node]
|
||||
string prettyNodeForInlineTest(DataFlow::Node node) {
|
||||
exists(node.asExpr()) and
|
||||
result = prettyExpr(node.asExpr())
|
||||
or
|
||||
exists(Expr e | e = node.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() |
|
||||
// since PostUpdateNode both has space in the `[post <thing>]` annotation, and does
|
||||
// not pretty print the pre-update node, we do custom handling of this.
|
||||
result = "[post]" + prettyExpr(e)
|
||||
)
|
||||
or
|
||||
not exists(node.asExpr()) and
|
||||
not exists(Expr e | e = node.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr()) and
|
||||
result = node.toString()
|
||||
}
|
||||
Reference in New Issue
Block a user