mirror of
https://github.com/github/codeql.git
synced 2025-12-20 18:56:32 +01:00
This commit does a lot of stuff all at once, so here are the main highlights: In `TypeTracker.qll`, we change `StepSummary::step` to step only between source nodes. Because reads and writes of global variables happen in two different (jump) steps, this requires the intermediate `ModuleVariableNode` to _also_ be a `LocalSourceNode`, and we therefore modify the charpred for that class accordingly. (This also means changing a few of the tests to account for these new source nodes.) In addition, we change `TypeTracker::step` to likewise step between local source nodes. Next, to enable the use of the `track` convenience method on nodes, we add some pragmas to `TypeTracker::step` that prevent bad joins from occurring. With this, we can eliminate all of the manual type tracker join predicates. Next, we observe that because `StepSummary::step` now uses `flowsTo`, it automatically encapsulates all local-flow steps. In particular this means we do not have to use `typePreservingStep` in `smallstep`, but can use `jumpStep` directly. A similar observation applies to `TypeTracker::smallstep`. Having done this, we no longer need `typePreservingStep`, so we get rid of it.
35 lines
1.1 KiB
Plaintext
35 lines
1.1 KiB
Plaintext
import python
|
|
import semmle.python.dataflow.new.DataFlow
|
|
import TestUtilities.InlineExpectationsTest
|
|
import semmle.python.ApiGraphs
|
|
|
|
class ApiUseTest extends InlineExpectationsTest {
|
|
ApiUseTest() { this = "ApiUseTest" }
|
|
|
|
override string getARelevantTag() { result = "use" }
|
|
|
|
private predicate relevant_node(API::Node a, DataFlow::Node n, Location l) {
|
|
n = a.getAUse() and
|
|
l = n.getLocation() and
|
|
// Module variable nodes have no suitable location, so it's best to simply exclude them entirely
|
|
// from the inline tests.
|
|
not n instanceof DataFlow::ModuleVariableNode
|
|
}
|
|
|
|
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
|
exists(API::Node a, DataFlow::Node n | relevant_node(a, n, location) |
|
|
tag = "use" and
|
|
// Only report the longest path on this line:
|
|
value =
|
|
max(API::Node a2, Location l2 |
|
|
relevant_node(a2, _, l2) and
|
|
l2.getFile() = location.getFile() and
|
|
l2.getStartLine() = location.getStartLine()
|
|
|
|
|
a2.getPath()
|
|
) and
|
|
element = n.toString()
|
|
)
|
|
}
|
|
}
|