mirror of
https://github.com/github/codeql.git
synced 2025-12-24 12:46:34 +01:00
Merge branch 'main' of github.com:github/codeql into SharedDataflow_SequenceFlow
This commit is contained in:
@@ -26,7 +26,7 @@ predicate all_defined(ModuleValue exporter) {
|
||||
}
|
||||
|
||||
from ImportStar imp, ModuleValue exporter
|
||||
where import_star(imp, exporter) and not all_defined(exporter)
|
||||
where import_star(imp, exporter) and not all_defined(exporter) and not exporter.isAbsent()
|
||||
select imp,
|
||||
"Import pollutes the enclosing namespace, as the imported module $@ does not define '__all__'.",
|
||||
exporter, exporter.getName()
|
||||
|
||||
@@ -1066,7 +1066,7 @@ private module LocalFlowBigStep {
|
||||
* Holds if `node` can be the first node in a maximal subsequence of local
|
||||
* flow steps in a dataflow path.
|
||||
*/
|
||||
private predicate localFlowEntry(Node node, Configuration config) {
|
||||
predicate localFlowEntry(Node node, Configuration config) {
|
||||
nodeCand2(node, config) and
|
||||
(
|
||||
config.isSource(node) or
|
||||
@@ -1650,53 +1650,53 @@ private class AccessPathOption extends TAccessPathOption {
|
||||
* Holds if `node` is reachable with access path `ap` from a source in
|
||||
* the configuration `config`.
|
||||
*
|
||||
* The Boolean `fromArg` records whether the node is reached through an
|
||||
* The call context `cc` records whether the node is reached through an
|
||||
* argument in a call, and if so, `argAp` records the access path of that
|
||||
* argument.
|
||||
*/
|
||||
private predicate flowFwd(
|
||||
Node node, boolean fromArg, AccessPathOption argAp, AccessPathFront apf, AccessPath ap,
|
||||
Node node, CallContext cc, AccessPathOption argAp, AccessPathFront apf, AccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
flowFwd0(node, fromArg, argAp, apf, ap, config) and
|
||||
flowFwd0(node, cc, argAp, apf, ap, config) and
|
||||
flowCand(node, _, _, apf, config)
|
||||
}
|
||||
|
||||
private predicate flowFwd0(
|
||||
Node node, boolean fromArg, AccessPathOption argAp, AccessPathFront apf, AccessPath ap,
|
||||
Node node, CallContext cc, AccessPathOption argAp, AccessPathFront apf, AccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
flowCand(node, _, _, _, config) and
|
||||
config.isSource(node) and
|
||||
fromArg = false and
|
||||
cc instanceof CallContextAny and
|
||||
argAp = TAccessPathNone() and
|
||||
ap = TNil(getNodeType(node)) and
|
||||
apf = ap.(AccessPathNil).getFront()
|
||||
or
|
||||
flowCand(node, _, _, _, unbind(config)) and
|
||||
(
|
||||
exists(Node mid |
|
||||
flowFwd(mid, fromArg, argAp, apf, ap, config) and
|
||||
localFlowBigStep(mid, node, true, _, config, _)
|
||||
exists(Node mid, LocalCallContext localCC |
|
||||
flowFwdLocalEntry(mid, cc, argAp, apf, ap, localCC, config) and
|
||||
localFlowBigStep(mid, node, true, _, config, localCC)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathNil nil |
|
||||
flowFwd(mid, fromArg, argAp, _, nil, config) and
|
||||
localFlowBigStep(mid, node, false, apf, config, _) and
|
||||
exists(Node mid, AccessPathNil nil, LocalCallContext localCC |
|
||||
flowFwdLocalEntry(mid, cc, argAp, _, nil, localCC, config) and
|
||||
localFlowBigStep(mid, node, false, apf, config, localCC) and
|
||||
apf = ap.(AccessPathNil).getFront()
|
||||
)
|
||||
or
|
||||
exists(Node mid |
|
||||
flowFwd(mid, _, _, apf, ap, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
fromArg = false and
|
||||
cc instanceof CallContextAny and
|
||||
argAp = TAccessPathNone()
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathNil nil |
|
||||
flowFwd(mid, _, _, _, nil, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
fromArg = false and
|
||||
cc instanceof CallContextAny and
|
||||
argAp = TAccessPathNone() and
|
||||
ap = TNil(getNodeType(node)) and
|
||||
apf = ap.(AccessPathNil).getFront()
|
||||
@@ -1704,40 +1704,51 @@ private predicate flowFwd0(
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(TypedContent tc | flowFwdStore(node, tc, pop(tc, ap), apf, fromArg, argAp, config))
|
||||
exists(TypedContent tc | flowFwdStore(node, tc, pop(tc, ap), apf, cc, argAp, config))
|
||||
or
|
||||
// read
|
||||
exists(TypedContent tc |
|
||||
flowFwdRead(node, _, push(tc, ap), apf, fromArg, argAp, config) and
|
||||
flowFwdRead(node, _, push(tc, ap), apf, cc, argAp, config) and
|
||||
flowFwdConsCand(tc, apf, ap, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
flowFwdIn(_, node, _, _, apf, ap, config) and
|
||||
fromArg = true and
|
||||
flowFwdIn(_, node, _, cc, _, apf, ap, config) and
|
||||
if flowCand(node, true, _, apf, config)
|
||||
then argAp = TAccessPathSome(ap)
|
||||
else argAp = TAccessPathNone()
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
flowFwdOut(call, node, fromArg, argAp, apf, ap, config) and
|
||||
fromArg = false
|
||||
exists(DataFlowCallable c |
|
||||
flowFwdOut(call, node, any(CallContextNoCall innercc), c, argAp, apf, ap, config) and
|
||||
if reducedViableImplInReturn(c, call) then cc = TReturn(c, call) else cc = TAnyCallContext()
|
||||
)
|
||||
or
|
||||
exists(AccessPath argAp0 |
|
||||
flowFwdOutFromArg(call, node, argAp0, apf, ap, config) and
|
||||
flowFwdIsEntered(call, fromArg, argAp, argAp0, config)
|
||||
flowFwdIsEntered(call, cc, argAp, argAp0, config)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowFwdLocalEntry(
|
||||
Node node, CallContext cc, AccessPathOption argAp, AccessPathFront apf, AccessPath ap,
|
||||
LocalCallContext localCC, Configuration config
|
||||
) {
|
||||
flowFwd(node, cc, argAp, apf, ap, config) and
|
||||
localFlowEntry(node, config) and
|
||||
localCC = getLocalCallContext(cc, node.getEnclosingCallable())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowFwdStore(
|
||||
Node node, TypedContent tc, AccessPath ap0, AccessPathFront apf, boolean fromArg,
|
||||
Node node, TypedContent tc, AccessPath ap0, AccessPathFront apf, CallContext cc,
|
||||
AccessPathOption argAp, Configuration config
|
||||
) {
|
||||
exists(Node mid, AccessPathFront apf0 |
|
||||
flowFwd(mid, fromArg, argAp, apf0, ap0, config) and
|
||||
flowFwd(mid, cc, argAp, apf0, ap0, config) and
|
||||
flowFwdStore0(mid, tc, node, apf0, apf, config)
|
||||
)
|
||||
}
|
||||
@@ -1764,20 +1775,20 @@ private predicate flowFwdStore0(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowFwdRead0(
|
||||
Node node1, TypedContent tc, AccessPathFrontHead apf0, AccessPath ap0, Node node2,
|
||||
boolean fromArg, AccessPathOption argAp, Configuration config
|
||||
Node node1, TypedContent tc, AccessPathFrontHead apf0, AccessPath ap0, Node node2, CallContext cc,
|
||||
AccessPathOption argAp, Configuration config
|
||||
) {
|
||||
flowFwd(node1, fromArg, argAp, apf0, ap0, config) and
|
||||
flowFwd(node1, cc, argAp, apf0, ap0, config) and
|
||||
readCandFwd(node1, tc, apf0, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowFwdRead(
|
||||
Node node, AccessPathFrontHead apf0, AccessPath ap0, AccessPathFront apf, boolean fromArg,
|
||||
Node node, AccessPathFrontHead apf0, AccessPath ap0, AccessPathFront apf, CallContext cc,
|
||||
AccessPathOption argAp, Configuration config
|
||||
) {
|
||||
exists(Node mid, TypedContent tc |
|
||||
flowFwdRead0(mid, tc, apf0, ap0, node, fromArg, argAp, config) and
|
||||
flowFwdRead0(mid, tc, apf0, ap0, node, cc, argAp, config) and
|
||||
flowCand(node, _, _, apf, unbind(config)) and
|
||||
flowCandConsCand(tc, apf, unbind(config))
|
||||
)
|
||||
@@ -1795,13 +1806,16 @@ private predicate flowFwdConsCand(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowFwdIn(
|
||||
DataFlowCall call, ParameterNode p, boolean fromArg, AccessPathOption argAp, AccessPathFront apf,
|
||||
AccessPath ap, Configuration config
|
||||
DataFlowCall call, ParameterNode p, CallContext outercc, CallContext innercc,
|
||||
AccessPathOption argAp, AccessPathFront apf, AccessPath ap, Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow |
|
||||
flowFwd(arg, fromArg, argAp, apf, ap, config) and
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow, DataFlowCallable c |
|
||||
flowFwd(arg, outercc, argAp, apf, ap, config) and
|
||||
flowIntoCallNodeCand2(call, arg, p, allowsFieldFlow, config) and
|
||||
flowCand(p, _, _, _, unbind(config))
|
||||
c = p.getEnclosingCallable() and
|
||||
c = resolveCall(call, outercc) and
|
||||
flowCand(p, _, _, _, unbind(config)) and
|
||||
if recordDataFlowCallSite(call, c) then innercc = TSpecificCall(call) else innercc = TSomeCall()
|
||||
|
|
||||
ap instanceof AccessPathNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1809,13 +1823,19 @@ private predicate flowFwdIn(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowFwdOut(
|
||||
DataFlowCall call, Node node, boolean fromArg, AccessPathOption argAp, AccessPathFront apf,
|
||||
AccessPath ap, Configuration config
|
||||
DataFlowCall call, Node node, CallContext innercc, DataFlowCallable innerc,
|
||||
AccessPathOption argAp, AccessPathFront apf, AccessPath ap, Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret, boolean allowsFieldFlow |
|
||||
flowFwd(ret, fromArg, argAp, apf, ap, config) and
|
||||
flowFwd(ret, innercc, argAp, apf, ap, config) and
|
||||
flowOutOfCallNodeCand2(call, ret, node, allowsFieldFlow, config) and
|
||||
flowCand(node, _, _, _, unbind(config))
|
||||
innerc = ret.getEnclosingCallable() and
|
||||
flowCand(node, _, _, _, unbind(config)) and
|
||||
(
|
||||
resolveReturn(innercc, innerc, call)
|
||||
or
|
||||
innercc.(CallContextCall).matchesCall(call)
|
||||
)
|
||||
|
|
||||
ap instanceof AccessPathNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1826,7 +1846,7 @@ private predicate flowFwdOutFromArg(
|
||||
DataFlowCall call, Node node, AccessPath argAp, AccessPathFront apf, AccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
flowFwdOut(call, node, true, TAccessPathSome(argAp), apf, ap, config)
|
||||
flowFwdOut(call, node, any(CallContextCall ccc), _, TAccessPathSome(argAp), apf, ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1834,10 +1854,10 @@ private predicate flowFwdOutFromArg(
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate flowFwdIsEntered(
|
||||
DataFlowCall call, boolean fromArg, AccessPathOption argAp, AccessPath ap, Configuration config
|
||||
DataFlowCall call, CallContext cc, AccessPathOption argAp, AccessPath ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, AccessPathFront apf |
|
||||
flowFwdIn(call, p, fromArg, argAp, apf, ap, config) and
|
||||
flowFwdIn(call, p, cc, _, argAp, apf, ap, config) and
|
||||
flowCand(p, true, TAccessPathFrontSome(_), apf, config)
|
||||
)
|
||||
}
|
||||
@@ -1920,7 +1940,7 @@ private predicate flow0(
|
||||
// flow out of a callable
|
||||
flowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if flowFwd(node, true, TAccessPathSome(_), _, ap, config)
|
||||
if flowFwd(node, any(CallContextCall ccc), TAccessPathSome(_), _, ap, config)
|
||||
then returnAp = TAccessPathSome(ap)
|
||||
else returnAp = TAccessPathNone()
|
||||
}
|
||||
@@ -2006,9 +2026,10 @@ private predicate flowIsReturned(
|
||||
DataFlowCall call, boolean toReturn, AccessPathOption returnAp, AccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret |
|
||||
exists(ReturnNodeExt ret, CallContextCall ccc |
|
||||
flowOut(call, ret, toReturn, returnAp, ap, config) and
|
||||
flowFwd(ret, true, TAccessPathSome(_), _, ap, config)
|
||||
flowFwd(ret, ccc, TAccessPathSome(_), _, ap, config) and
|
||||
ccc.matchesCall(call)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2031,7 +2052,7 @@ private newtype TSummaryCtx =
|
||||
exists(ReturnNodeExt ret, Configuration config, AccessPath ap0 |
|
||||
parameterFlow(p, ap, ret.getEnclosingCallable(), config) and
|
||||
flow(ret, true, TAccessPathSome(_), ap0, config) and
|
||||
flowFwd(ret, true, TAccessPathSome(ap), _, ap0, config)
|
||||
flowFwd(ret, any(CallContextCall ccc), TAccessPathSome(ap), _, ap0, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2352,7 +2373,7 @@ private predicate pathOutOfCallable0(
|
||||
) {
|
||||
pos = getReturnPosition(mid.getNode()) and
|
||||
innercc = mid.getCallContext() and
|
||||
not innercc instanceof CallContextCall and
|
||||
innercc instanceof CallContextNoCall and
|
||||
ap = mid.getAp() and
|
||||
config = mid.getConfiguration()
|
||||
}
|
||||
@@ -2867,7 +2888,7 @@ private module FlowExploration {
|
||||
) {
|
||||
pos = getReturnPosition(mid.getNode()) and
|
||||
innercc = mid.getCallContext() and
|
||||
not innercc instanceof CallContextCall and
|
||||
innercc instanceof CallContextNoCall and
|
||||
ap = mid.getAp() and
|
||||
config = mid.getConfiguration()
|
||||
}
|
||||
|
||||
@@ -1066,7 +1066,7 @@ private module LocalFlowBigStep {
|
||||
* Holds if `node` can be the first node in a maximal subsequence of local
|
||||
* flow steps in a dataflow path.
|
||||
*/
|
||||
private predicate localFlowEntry(Node node, Configuration config) {
|
||||
predicate localFlowEntry(Node node, Configuration config) {
|
||||
nodeCand2(node, config) and
|
||||
(
|
||||
config.isSource(node) or
|
||||
@@ -1650,53 +1650,53 @@ private class AccessPathOption extends TAccessPathOption {
|
||||
* Holds if `node` is reachable with access path `ap` from a source in
|
||||
* the configuration `config`.
|
||||
*
|
||||
* The Boolean `fromArg` records whether the node is reached through an
|
||||
* The call context `cc` records whether the node is reached through an
|
||||
* argument in a call, and if so, `argAp` records the access path of that
|
||||
* argument.
|
||||
*/
|
||||
private predicate flowFwd(
|
||||
Node node, boolean fromArg, AccessPathOption argAp, AccessPathFront apf, AccessPath ap,
|
||||
Node node, CallContext cc, AccessPathOption argAp, AccessPathFront apf, AccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
flowFwd0(node, fromArg, argAp, apf, ap, config) and
|
||||
flowFwd0(node, cc, argAp, apf, ap, config) and
|
||||
flowCand(node, _, _, apf, config)
|
||||
}
|
||||
|
||||
private predicate flowFwd0(
|
||||
Node node, boolean fromArg, AccessPathOption argAp, AccessPathFront apf, AccessPath ap,
|
||||
Node node, CallContext cc, AccessPathOption argAp, AccessPathFront apf, AccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
flowCand(node, _, _, _, config) and
|
||||
config.isSource(node) and
|
||||
fromArg = false and
|
||||
cc instanceof CallContextAny and
|
||||
argAp = TAccessPathNone() and
|
||||
ap = TNil(getNodeType(node)) and
|
||||
apf = ap.(AccessPathNil).getFront()
|
||||
or
|
||||
flowCand(node, _, _, _, unbind(config)) and
|
||||
(
|
||||
exists(Node mid |
|
||||
flowFwd(mid, fromArg, argAp, apf, ap, config) and
|
||||
localFlowBigStep(mid, node, true, _, config, _)
|
||||
exists(Node mid, LocalCallContext localCC |
|
||||
flowFwdLocalEntry(mid, cc, argAp, apf, ap, localCC, config) and
|
||||
localFlowBigStep(mid, node, true, _, config, localCC)
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathNil nil |
|
||||
flowFwd(mid, fromArg, argAp, _, nil, config) and
|
||||
localFlowBigStep(mid, node, false, apf, config, _) and
|
||||
exists(Node mid, AccessPathNil nil, LocalCallContext localCC |
|
||||
flowFwdLocalEntry(mid, cc, argAp, _, nil, localCC, config) and
|
||||
localFlowBigStep(mid, node, false, apf, config, localCC) and
|
||||
apf = ap.(AccessPathNil).getFront()
|
||||
)
|
||||
or
|
||||
exists(Node mid |
|
||||
flowFwd(mid, _, _, apf, ap, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
fromArg = false and
|
||||
cc instanceof CallContextAny and
|
||||
argAp = TAccessPathNone()
|
||||
)
|
||||
or
|
||||
exists(Node mid, AccessPathNil nil |
|
||||
flowFwd(mid, _, _, _, nil, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
fromArg = false and
|
||||
cc instanceof CallContextAny and
|
||||
argAp = TAccessPathNone() and
|
||||
ap = TNil(getNodeType(node)) and
|
||||
apf = ap.(AccessPathNil).getFront()
|
||||
@@ -1704,40 +1704,51 @@ private predicate flowFwd0(
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(TypedContent tc | flowFwdStore(node, tc, pop(tc, ap), apf, fromArg, argAp, config))
|
||||
exists(TypedContent tc | flowFwdStore(node, tc, pop(tc, ap), apf, cc, argAp, config))
|
||||
or
|
||||
// read
|
||||
exists(TypedContent tc |
|
||||
flowFwdRead(node, _, push(tc, ap), apf, fromArg, argAp, config) and
|
||||
flowFwdRead(node, _, push(tc, ap), apf, cc, argAp, config) and
|
||||
flowFwdConsCand(tc, apf, ap, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
flowFwdIn(_, node, _, _, apf, ap, config) and
|
||||
fromArg = true and
|
||||
flowFwdIn(_, node, _, cc, _, apf, ap, config) and
|
||||
if flowCand(node, true, _, apf, config)
|
||||
then argAp = TAccessPathSome(ap)
|
||||
else argAp = TAccessPathNone()
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
flowFwdOut(call, node, fromArg, argAp, apf, ap, config) and
|
||||
fromArg = false
|
||||
exists(DataFlowCallable c |
|
||||
flowFwdOut(call, node, any(CallContextNoCall innercc), c, argAp, apf, ap, config) and
|
||||
if reducedViableImplInReturn(c, call) then cc = TReturn(c, call) else cc = TAnyCallContext()
|
||||
)
|
||||
or
|
||||
exists(AccessPath argAp0 |
|
||||
flowFwdOutFromArg(call, node, argAp0, apf, ap, config) and
|
||||
flowFwdIsEntered(call, fromArg, argAp, argAp0, config)
|
||||
flowFwdIsEntered(call, cc, argAp, argAp0, config)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowFwdLocalEntry(
|
||||
Node node, CallContext cc, AccessPathOption argAp, AccessPathFront apf, AccessPath ap,
|
||||
LocalCallContext localCC, Configuration config
|
||||
) {
|
||||
flowFwd(node, cc, argAp, apf, ap, config) and
|
||||
localFlowEntry(node, config) and
|
||||
localCC = getLocalCallContext(cc, node.getEnclosingCallable())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowFwdStore(
|
||||
Node node, TypedContent tc, AccessPath ap0, AccessPathFront apf, boolean fromArg,
|
||||
Node node, TypedContent tc, AccessPath ap0, AccessPathFront apf, CallContext cc,
|
||||
AccessPathOption argAp, Configuration config
|
||||
) {
|
||||
exists(Node mid, AccessPathFront apf0 |
|
||||
flowFwd(mid, fromArg, argAp, apf0, ap0, config) and
|
||||
flowFwd(mid, cc, argAp, apf0, ap0, config) and
|
||||
flowFwdStore0(mid, tc, node, apf0, apf, config)
|
||||
)
|
||||
}
|
||||
@@ -1764,20 +1775,20 @@ private predicate flowFwdStore0(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowFwdRead0(
|
||||
Node node1, TypedContent tc, AccessPathFrontHead apf0, AccessPath ap0, Node node2,
|
||||
boolean fromArg, AccessPathOption argAp, Configuration config
|
||||
Node node1, TypedContent tc, AccessPathFrontHead apf0, AccessPath ap0, Node node2, CallContext cc,
|
||||
AccessPathOption argAp, Configuration config
|
||||
) {
|
||||
flowFwd(node1, fromArg, argAp, apf0, ap0, config) and
|
||||
flowFwd(node1, cc, argAp, apf0, ap0, config) and
|
||||
readCandFwd(node1, tc, apf0, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowFwdRead(
|
||||
Node node, AccessPathFrontHead apf0, AccessPath ap0, AccessPathFront apf, boolean fromArg,
|
||||
Node node, AccessPathFrontHead apf0, AccessPath ap0, AccessPathFront apf, CallContext cc,
|
||||
AccessPathOption argAp, Configuration config
|
||||
) {
|
||||
exists(Node mid, TypedContent tc |
|
||||
flowFwdRead0(mid, tc, apf0, ap0, node, fromArg, argAp, config) and
|
||||
flowFwdRead0(mid, tc, apf0, ap0, node, cc, argAp, config) and
|
||||
flowCand(node, _, _, apf, unbind(config)) and
|
||||
flowCandConsCand(tc, apf, unbind(config))
|
||||
)
|
||||
@@ -1795,13 +1806,16 @@ private predicate flowFwdConsCand(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowFwdIn(
|
||||
DataFlowCall call, ParameterNode p, boolean fromArg, AccessPathOption argAp, AccessPathFront apf,
|
||||
AccessPath ap, Configuration config
|
||||
DataFlowCall call, ParameterNode p, CallContext outercc, CallContext innercc,
|
||||
AccessPathOption argAp, AccessPathFront apf, AccessPath ap, Configuration config
|
||||
) {
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow |
|
||||
flowFwd(arg, fromArg, argAp, apf, ap, config) and
|
||||
exists(ArgumentNode arg, boolean allowsFieldFlow, DataFlowCallable c |
|
||||
flowFwd(arg, outercc, argAp, apf, ap, config) and
|
||||
flowIntoCallNodeCand2(call, arg, p, allowsFieldFlow, config) and
|
||||
flowCand(p, _, _, _, unbind(config))
|
||||
c = p.getEnclosingCallable() and
|
||||
c = resolveCall(call, outercc) and
|
||||
flowCand(p, _, _, _, unbind(config)) and
|
||||
if recordDataFlowCallSite(call, c) then innercc = TSpecificCall(call) else innercc = TSomeCall()
|
||||
|
|
||||
ap instanceof AccessPathNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1809,13 +1823,19 @@ private predicate flowFwdIn(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowFwdOut(
|
||||
DataFlowCall call, Node node, boolean fromArg, AccessPathOption argAp, AccessPathFront apf,
|
||||
AccessPath ap, Configuration config
|
||||
DataFlowCall call, Node node, CallContext innercc, DataFlowCallable innerc,
|
||||
AccessPathOption argAp, AccessPathFront apf, AccessPath ap, Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret, boolean allowsFieldFlow |
|
||||
flowFwd(ret, fromArg, argAp, apf, ap, config) and
|
||||
flowFwd(ret, innercc, argAp, apf, ap, config) and
|
||||
flowOutOfCallNodeCand2(call, ret, node, allowsFieldFlow, config) and
|
||||
flowCand(node, _, _, _, unbind(config))
|
||||
innerc = ret.getEnclosingCallable() and
|
||||
flowCand(node, _, _, _, unbind(config)) and
|
||||
(
|
||||
resolveReturn(innercc, innerc, call)
|
||||
or
|
||||
innercc.(CallContextCall).matchesCall(call)
|
||||
)
|
||||
|
|
||||
ap instanceof AccessPathNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1826,7 +1846,7 @@ private predicate flowFwdOutFromArg(
|
||||
DataFlowCall call, Node node, AccessPath argAp, AccessPathFront apf, AccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
flowFwdOut(call, node, true, TAccessPathSome(argAp), apf, ap, config)
|
||||
flowFwdOut(call, node, any(CallContextCall ccc), _, TAccessPathSome(argAp), apf, ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1834,10 +1854,10 @@ private predicate flowFwdOutFromArg(
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate flowFwdIsEntered(
|
||||
DataFlowCall call, boolean fromArg, AccessPathOption argAp, AccessPath ap, Configuration config
|
||||
DataFlowCall call, CallContext cc, AccessPathOption argAp, AccessPath ap, Configuration config
|
||||
) {
|
||||
exists(ParameterNode p, AccessPathFront apf |
|
||||
flowFwdIn(call, p, fromArg, argAp, apf, ap, config) and
|
||||
flowFwdIn(call, p, cc, _, argAp, apf, ap, config) and
|
||||
flowCand(p, true, TAccessPathFrontSome(_), apf, config)
|
||||
)
|
||||
}
|
||||
@@ -1920,7 +1940,7 @@ private predicate flow0(
|
||||
// flow out of a callable
|
||||
flowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if flowFwd(node, true, TAccessPathSome(_), _, ap, config)
|
||||
if flowFwd(node, any(CallContextCall ccc), TAccessPathSome(_), _, ap, config)
|
||||
then returnAp = TAccessPathSome(ap)
|
||||
else returnAp = TAccessPathNone()
|
||||
}
|
||||
@@ -2006,9 +2026,10 @@ private predicate flowIsReturned(
|
||||
DataFlowCall call, boolean toReturn, AccessPathOption returnAp, AccessPath ap,
|
||||
Configuration config
|
||||
) {
|
||||
exists(ReturnNodeExt ret |
|
||||
exists(ReturnNodeExt ret, CallContextCall ccc |
|
||||
flowOut(call, ret, toReturn, returnAp, ap, config) and
|
||||
flowFwd(ret, true, TAccessPathSome(_), _, ap, config)
|
||||
flowFwd(ret, ccc, TAccessPathSome(_), _, ap, config) and
|
||||
ccc.matchesCall(call)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2031,7 +2052,7 @@ private newtype TSummaryCtx =
|
||||
exists(ReturnNodeExt ret, Configuration config, AccessPath ap0 |
|
||||
parameterFlow(p, ap, ret.getEnclosingCallable(), config) and
|
||||
flow(ret, true, TAccessPathSome(_), ap0, config) and
|
||||
flowFwd(ret, true, TAccessPathSome(ap), _, ap0, config)
|
||||
flowFwd(ret, any(CallContextCall ccc), TAccessPathSome(ap), _, ap0, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2352,7 +2373,7 @@ private predicate pathOutOfCallable0(
|
||||
) {
|
||||
pos = getReturnPosition(mid.getNode()) and
|
||||
innercc = mid.getCallContext() and
|
||||
not innercc instanceof CallContextCall and
|
||||
innercc instanceof CallContextNoCall and
|
||||
ap = mid.getAp() and
|
||||
config = mid.getConfiguration()
|
||||
}
|
||||
@@ -2867,7 +2888,7 @@ private module FlowExploration {
|
||||
) {
|
||||
pos = getReturnPosition(mid.getNode()) and
|
||||
innercc = mid.getCallContext() and
|
||||
not innercc instanceof CallContextCall and
|
||||
innercc instanceof CallContextNoCall and
|
||||
ap = mid.getAp() and
|
||||
config = mid.getConfiguration()
|
||||
}
|
||||
|
||||
@@ -512,13 +512,19 @@ abstract class CallContext extends TCallContext {
|
||||
abstract predicate relevantFor(DataFlowCallable callable);
|
||||
}
|
||||
|
||||
class CallContextAny extends CallContext, TAnyCallContext {
|
||||
abstract class CallContextNoCall extends CallContext { }
|
||||
|
||||
class CallContextAny extends CallContextNoCall, TAnyCallContext {
|
||||
override string toString() { result = "CcAny" }
|
||||
|
||||
override predicate relevantFor(DataFlowCallable callable) { any() }
|
||||
}
|
||||
|
||||
abstract class CallContextCall extends CallContext { }
|
||||
abstract class CallContextCall extends CallContext {
|
||||
/** Holds if this call context may be `call`. */
|
||||
bindingset[call]
|
||||
abstract predicate matchesCall(DataFlowCall call);
|
||||
}
|
||||
|
||||
class CallContextSpecificCall extends CallContextCall, TSpecificCall {
|
||||
override string toString() {
|
||||
@@ -529,6 +535,8 @@ class CallContextSpecificCall extends CallContextCall, TSpecificCall {
|
||||
recordDataFlowCallSite(getCall(), callable)
|
||||
}
|
||||
|
||||
override predicate matchesCall(DataFlowCall call) { call = this.getCall() }
|
||||
|
||||
DataFlowCall getCall() { this = TSpecificCall(result) }
|
||||
}
|
||||
|
||||
@@ -538,9 +546,11 @@ class CallContextSomeCall extends CallContextCall, TSomeCall {
|
||||
override predicate relevantFor(DataFlowCallable callable) {
|
||||
exists(ParameterNode p | p.getEnclosingCallable() = callable)
|
||||
}
|
||||
|
||||
override predicate matchesCall(DataFlowCall call) { any() }
|
||||
}
|
||||
|
||||
class CallContextReturn extends CallContext, TReturn {
|
||||
class CallContextReturn extends CallContextNoCall, TReturn {
|
||||
override string toString() {
|
||||
exists(DataFlowCall call | this = TReturn(_, call) | result = "CcReturn(" + call + ")")
|
||||
}
|
||||
|
||||
@@ -97,8 +97,65 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
//--------
|
||||
// Global flow
|
||||
//--------
|
||||
/**
|
||||
* IPA type for DataFlowCallable.
|
||||
* A callable is either a callable value or a class.
|
||||
*/
|
||||
newtype TDataFlowCallable =
|
||||
TCallableValue(CallableValue callable) or
|
||||
TClassValue(ClassValue c)
|
||||
|
||||
/** Represents a callable */
|
||||
class DataFlowCallable = CallableValue;
|
||||
abstract class DataFlowCallable extends TDataFlowCallable {
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
|
||||
/** Gets a call to this callable. */
|
||||
abstract CallNode getACall();
|
||||
|
||||
/** Gets the scope of this callable */
|
||||
abstract Scope getScope();
|
||||
|
||||
/** Gets the specified parameter of this callable */
|
||||
abstract NameNode getParameter(int n);
|
||||
|
||||
/** Gets the name of this callable. */
|
||||
abstract string getName();
|
||||
}
|
||||
|
||||
class DataFlowCallableValue extends DataFlowCallable, TCallableValue {
|
||||
CallableValue callable;
|
||||
|
||||
DataFlowCallableValue() { this = TCallableValue(callable) }
|
||||
|
||||
override string toString() { result = callable.toString() }
|
||||
|
||||
override CallNode getACall() { result = callable.getACall() }
|
||||
|
||||
override Scope getScope() { result = callable.getScope() }
|
||||
|
||||
override NameNode getParameter(int n) { result = callable.getParameter(n) }
|
||||
|
||||
override string getName() { result = callable.getName() }
|
||||
}
|
||||
|
||||
class DataFlowClassValue extends DataFlowCallable, TClassValue {
|
||||
ClassValue c;
|
||||
|
||||
DataFlowClassValue() { this = TClassValue(c) }
|
||||
|
||||
override string toString() { result = c.toString() }
|
||||
|
||||
override CallNode getACall() { result = c.getACall() }
|
||||
|
||||
override Scope getScope() { result = c.getScope() }
|
||||
|
||||
override NameNode getParameter(int n) {
|
||||
result.getNode() = c.getScope().getInitMethod().getArg(n + 1).asName()
|
||||
}
|
||||
|
||||
override string getName() { result = c.getName() }
|
||||
}
|
||||
|
||||
/** Represents a call to a callable */
|
||||
class DataFlowCall extends CallNode {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import callGraphConfig
|
||||
import experimental.dataflow.callGraphConfig
|
||||
|
||||
from DataFlow::Node source, DataFlow::Node sink
|
||||
where exists(CallGraphConfig cfg | cfg.hasFlow(source, sink))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import callGraphConfig
|
||||
import experimental.dataflow.callGraphConfig
|
||||
|
||||
from DataFlow::Node sink
|
||||
where exists(CallGraphConfig cfg | cfg.isSink(sink))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import callGraphConfig
|
||||
import experimental.dataflow.callGraphConfig
|
||||
|
||||
from DataFlow::Node source
|
||||
where exists(CallGraphConfig cfg | cfg.isSource(source))
|
||||
|
||||
@@ -103,3 +103,5 @@ argHasPostUpdate
|
||||
| test.py:74:17:74:17 | ControlFlowNode for t | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.py:81:13:81:13 | ControlFlowNode for t | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.py:86:13:86:13 | ControlFlowNode for t | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.py:158:15:158:15 | ControlFlowNode for l | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.py:159:15:159:15 | ControlFlowNode for d | ArgumentNode is missing PostUpdateNode. |
|
||||
|
||||
1228
python/ql/test/experimental/dataflow/coverage/classes.py
Normal file
1228
python/ql/test/experimental/dataflow/coverage/classes.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
| classes.py:19:12:19:31 | ControlFlowNode for Attribute() | classes.py:19:12:19:31 | ControlFlowNode for Attribute() |
|
||||
| classes.py:174:7:174:22 | ControlFlowNode for set() | classes.py:174:7:174:22 | ControlFlowNode for set() |
|
||||
| classes.py:178:7:178:28 | ControlFlowNode for frozenset() | classes.py:178:7:178:28 | ControlFlowNode for frozenset() |
|
||||
| classes.py:182:7:182:26 | ControlFlowNode for dict() | classes.py:182:7:182:26 | ControlFlowNode for dict() |
|
||||
| classes.py:303:28:303:51 | ControlFlowNode for dict() | classes.py:303:28:303:51 | ControlFlowNode for dict() |
|
||||
| classes.py:466:12:466:24 | ControlFlowNode for Attribute() | classes.py:466:12:466:24 | ControlFlowNode for Attribute() |
|
||||
@@ -0,0 +1,10 @@
|
||||
import experimental.dataflow.callGraphConfig
|
||||
|
||||
from DataFlow::Node source, DataFlow::Node sink
|
||||
where
|
||||
source.getLocation().getFile().getBaseName() = "classes.py" and
|
||||
sink.getLocation().getFile().getBaseName() = "classes.py" and
|
||||
exists(CallGraphConfig cfg | cfg.hasFlow(source, sink))
|
||||
select source, sink
|
||||
// Ideally, we would just have 1-step paths either from argument to parameter
|
||||
// or from return to call. This gives a bit more, so should be rewritten.
|
||||
@@ -1,135 +1,263 @@
|
||||
edges
|
||||
| test.py:24:10:24:26 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:25:9:25:9 | ControlFlowNode for x [Tuple element at index 1] |
|
||||
| test.py:24:21:24:26 | ControlFlowNode for SOURCE | test.py:24:10:24:26 | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:25:9:25:9 | ControlFlowNode for x [Tuple element at index 1] | test.py:25:9:25:12 | ControlFlowNode for Subscript |
|
||||
| test.py:25:9:25:12 | ControlFlowNode for Subscript | test.py:26:10:26:10 | ControlFlowNode for y |
|
||||
| test.py:35:9:35:14 | ControlFlowNode for SOURCE | test.py:36:10:36:10 | ControlFlowNode for x |
|
||||
| test.py:40:9:40:16 | ControlFlowNode for Str | test.py:41:10:41:10 | ControlFlowNode for x |
|
||||
| test.py:44:9:44:17 | ControlFlowNode for Str | test.py:45:10:45:10 | ControlFlowNode for x |
|
||||
| test.py:48:9:48:10 | ControlFlowNode for IntegerLiteral | test.py:49:10:49:10 | ControlFlowNode for x |
|
||||
| test.py:52:9:52:12 | ControlFlowNode for FloatLiteral | test.py:53:10:53:10 | ControlFlowNode for x |
|
||||
| test.py:61:10:61:15 | ControlFlowNode for SOURCE | test.py:62:10:62:10 | ControlFlowNode for x |
|
||||
| test.py:66:9:66:16 | ControlFlowNode for List [List element] | test.py:67:10:67:10 | ControlFlowNode for x [List element] |
|
||||
| test.py:66:10:66:15 | ControlFlowNode for SOURCE | test.py:66:9:66:16 | ControlFlowNode for List [List element] |
|
||||
| test.py:67:10:67:10 | ControlFlowNode for x [List element] | test.py:67:10:67:13 | ControlFlowNode for Subscript |
|
||||
| test.py:74:9:74:37 | ControlFlowNode for ListComp [List element] | test.py:75:10:75:10 | ControlFlowNode for x [List element] |
|
||||
| test.py:74:10:74:15 | ControlFlowNode for SOURCE | test.py:74:9:74:37 | ControlFlowNode for ListComp [List element] |
|
||||
| datamodel.py:13:1:13:6 | GSSA Variable SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() |
|
||||
| datamodel.py:13:1:13:6 | GSSA Variable SOURCE | datamodel.py:38:6:38:17 | GSSA Variable SOURCE |
|
||||
| datamodel.py:13:1:13:6 | GSSA Variable SOURCE | datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:13:1:13:6 | GSSA Variable SOURCE |
|
||||
| datamodel.py:38:6:38:17 | GSSA Variable SOURCE | datamodel.py:65:5:65:7 | ControlFlowNode for C() |
|
||||
| datamodel.py:38:6:38:17 | GSSA Variable SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:38:6:38:17 | GSSA Variable SOURCE | datamodel.py:71:6:71:24 | GSSA Variable SOURCE |
|
||||
| datamodel.py:38:6:38:17 | GSSA Variable SOURCE | datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() |
|
||||
| datamodel.py:65:1:65:1 | GSSA Variable c | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:65:1:65:1 | GSSA Variable c | datamodel.py:71:6:71:24 | GSSA Variable c |
|
||||
| datamodel.py:65:5:65:7 | ControlFlowNode for C() | datamodel.py:65:1:65:1 | GSSA Variable c |
|
||||
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | datamodel.py:73:6:73:27 | ControlFlowNode for func_obj() |
|
||||
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | datamodel.py:80:6:80:26 | GSSA Variable SOURCE |
|
||||
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:71:6:71:24 | GSSA Variable c | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:71:6:71:24 | GSSA Variable c | datamodel.py:72:6:72:27 | GSSA Variable c |
|
||||
| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:72:6:72:27 | GSSA Variable c | datamodel.py:73:6:73:27 | ControlFlowNode for func_obj() |
|
||||
| datamodel.py:72:6:72:27 | GSSA Variable c | datamodel.py:73:6:73:27 | GSSA Variable c |
|
||||
| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:73:6:73:27 | GSSA Variable c | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:73:6:73:27 | GSSA Variable c | datamodel.py:80:6:80:26 | GSSA Variable c |
|
||||
| datamodel.py:80:6:80:26 | GSSA Variable SOURCE | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:80:6:80:26 | GSSA Variable SOURCE | datamodel.py:81:6:81:26 | GSSA Variable SOURCE |
|
||||
| datamodel.py:80:6:80:26 | GSSA Variable SOURCE | datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:80:6:80:26 | GSSA Variable c | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:80:6:80:26 | GSSA Variable c | datamodel.py:82:6:82:26 | ControlFlowNode for c_func_obj() |
|
||||
| datamodel.py:80:6:80:26 | GSSA Variable c | datamodel.py:92:8:92:21 | ControlFlowNode for gen() |
|
||||
| datamodel.py:80:6:80:26 | GSSA Variable c | datamodel.py:93:6:93:20 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:80:6:80:26 | GSSA Variable c | datamodel.py:96:9:96:24 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:80:6:80:26 | GSSA Variable c | datamodel.py:96:9:96:24 | GSSA Variable c |
|
||||
| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:81:6:81:26 | GSSA Variable SOURCE | datamodel.py:82:6:82:26 | ControlFlowNode for c_func_obj() |
|
||||
| datamodel.py:81:6:81:26 | GSSA Variable SOURCE | datamodel.py:92:8:92:21 | ControlFlowNode for gen() |
|
||||
| datamodel.py:81:6:81:26 | GSSA Variable SOURCE | datamodel.py:92:8:92:21 | GSSA Variable SOURCE |
|
||||
| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:92:1:92:4 | GSSA Variable iter | datamodel.py:93:6:93:20 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:92:1:92:4 | GSSA Variable iter | datamodel.py:93:6:93:20 | GSSA Variable iter |
|
||||
| datamodel.py:92:8:92:21 | ControlFlowNode for gen() | datamodel.py:92:1:92:4 | GSSA Variable iter |
|
||||
| datamodel.py:92:8:92:21 | GSSA Variable SOURCE | datamodel.py:93:6:93:20 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:92:8:92:21 | GSSA Variable SOURCE | datamodel.py:96:9:96:24 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:92:8:92:21 | GSSA Variable SOURCE | datamodel.py:96:9:96:24 | GSSA Variable SOURCE |
|
||||
| datamodel.py:93:6:93:20 | GSSA Variable iter | datamodel.py:96:9:96:24 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:93:6:93:20 | GSSA Variable iter | datamodel.py:97:6:97:21 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:93:6:93:20 | GSSA Variable iter | datamodel.py:106:6:106:30 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:93:6:93:20 | GSSA Variable iter | datamodel.py:107:6:107:32 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:93:6:93:20 | GSSA Variable iter | datamodel.py:119:6:119:30 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:96:1:96:5 | GSSA Variable oiter | datamodel.py:97:6:97:21 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:96:1:96:5 | GSSA Variable oiter | datamodel.py:97:6:97:21 | GSSA Variable oiter |
|
||||
| datamodel.py:96:9:96:24 | ControlFlowNode for Attribute() | datamodel.py:96:1:96:5 | GSSA Variable oiter |
|
||||
| datamodel.py:96:9:96:24 | GSSA Variable SOURCE | datamodel.py:97:6:97:21 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:96:9:96:24 | GSSA Variable SOURCE | datamodel.py:106:18:106:29 | GSSA Variable SOURCE |
|
||||
| datamodel.py:96:9:96:24 | GSSA Variable c | datamodel.py:97:6:97:21 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:96:9:96:24 | GSSA Variable c | datamodel.py:106:6:106:30 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:96:9:96:24 | GSSA Variable c | datamodel.py:107:18:107:31 | GSSA Variable c |
|
||||
| datamodel.py:97:6:97:21 | GSSA Variable oiter | datamodel.py:106:6:106:30 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:97:6:97:21 | GSSA Variable oiter | datamodel.py:107:6:107:32 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:97:6:97:21 | GSSA Variable oiter | datamodel.py:119:6:119:30 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:106:18:106:29 | GSSA Variable SOURCE | datamodel.py:106:6:106:30 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:106:18:106:29 | GSSA Variable SOURCE | datamodel.py:107:18:107:31 | GSSA Variable SOURCE |
|
||||
| datamodel.py:107:18:107:31 | GSSA Variable SOURCE | datamodel.py:107:6:107:32 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:107:18:107:31 | GSSA Variable SOURCE | datamodel.py:119:18:119:29 | GSSA Variable SOURCE |
|
||||
| datamodel.py:107:18:107:31 | GSSA Variable c | datamodel.py:107:6:107:32 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:107:18:107:31 | GSSA Variable c | datamodel.py:119:6:119:30 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:119:18:119:29 | GSSA Variable SOURCE | datamodel.py:119:6:119:30 | ControlFlowNode for Attribute() |
|
||||
| test.py:32:10:32:26 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:33:9:33:9 | ControlFlowNode for x [Tuple element at index 1] |
|
||||
| test.py:32:21:32:26 | ControlFlowNode for SOURCE | test.py:32:10:32:26 | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:33:9:33:9 | ControlFlowNode for x [Tuple element at index 1] | test.py:33:9:33:12 | ControlFlowNode for Subscript |
|
||||
| test.py:33:9:33:12 | ControlFlowNode for Subscript | test.py:34:10:34:10 | ControlFlowNode for y |
|
||||
| test.py:43:9:43:14 | ControlFlowNode for SOURCE | test.py:44:10:44:10 | ControlFlowNode for x |
|
||||
| test.py:48:9:48:16 | ControlFlowNode for Str | test.py:49:10:49:10 | ControlFlowNode for x |
|
||||
| test.py:52:9:52:17 | ControlFlowNode for Str | test.py:53:10:53:10 | ControlFlowNode for x |
|
||||
| test.py:56:9:56:10 | ControlFlowNode for IntegerLiteral | test.py:57:10:57:10 | ControlFlowNode for x |
|
||||
| test.py:60:9:60:12 | ControlFlowNode for FloatLiteral | test.py:61:10:61:10 | ControlFlowNode for x |
|
||||
| test.py:69:10:69:15 | ControlFlowNode for SOURCE | test.py:70:10:70:10 | ControlFlowNode for x |
|
||||
| test.py:74:9:74:16 | ControlFlowNode for List [List element] | test.py:75:10:75:10 | ControlFlowNode for x [List element] |
|
||||
| test.py:74:10:74:15 | ControlFlowNode for SOURCE | test.py:74:9:74:16 | ControlFlowNode for List [List element] |
|
||||
| test.py:75:10:75:10 | ControlFlowNode for x [List element] | test.py:75:10:75:13 | ControlFlowNode for Subscript |
|
||||
| test.py:78:9:78:29 | ControlFlowNode for ListComp [List element] | test.py:79:10:79:10 | ControlFlowNode for x [List element] |
|
||||
| test.py:78:10:78:10 | ControlFlowNode for y | test.py:78:9:78:29 | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:78:16:78:16 | SSA variable y | test.py:78:10:78:10 | ControlFlowNode for y |
|
||||
| test.py:78:21:78:28 | ControlFlowNode for List [List element] | test.py:78:16:78:16 | SSA variable y |
|
||||
| test.py:78:22:78:27 | ControlFlowNode for SOURCE | test.py:78:21:78:28 | ControlFlowNode for List [List element] |
|
||||
| test.py:79:10:79:10 | ControlFlowNode for x [List element] | test.py:79:10:79:13 | ControlFlowNode for Subscript |
|
||||
| test.py:91:9:91:37 | ControlFlowNode for SetComp [Set element] | test.py:92:10:92:10 | ControlFlowNode for x [Set element] |
|
||||
| test.py:91:10:91:15 | ControlFlowNode for SOURCE | test.py:91:9:91:37 | ControlFlowNode for SetComp [Set element] |
|
||||
| test.py:92:10:92:10 | ControlFlowNode for x [Set element] | test.py:92:10:92:16 | ControlFlowNode for Attribute() |
|
||||
| test.py:95:9:95:29 | ControlFlowNode for SetComp [Set element] | test.py:96:10:96:10 | ControlFlowNode for x [Set element] |
|
||||
| test.py:95:10:95:10 | ControlFlowNode for y | test.py:95:9:95:29 | ControlFlowNode for SetComp [Set element] |
|
||||
| test.py:95:16:95:16 | SSA variable y | test.py:95:10:95:10 | ControlFlowNode for y |
|
||||
| test.py:95:21:95:28 | ControlFlowNode for List [List element] | test.py:95:16:95:16 | SSA variable y |
|
||||
| test.py:95:22:95:27 | ControlFlowNode for SOURCE | test.py:95:21:95:28 | ControlFlowNode for List [List element] |
|
||||
| test.py:96:10:96:10 | ControlFlowNode for x [Set element] | test.py:96:10:96:16 | ControlFlowNode for Attribute() |
|
||||
| test.py:104:9:104:21 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:105:10:105:10 | ControlFlowNode for x [Dictionary element at key s] |
|
||||
| test.py:104:15:104:20 | ControlFlowNode for SOURCE | test.py:104:9:104:21 | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:105:10:105:10 | ControlFlowNode for x [Dictionary element at key s] | test.py:105:10:105:15 | ControlFlowNode for Subscript |
|
||||
| test.py:108:9:108:21 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:109:10:109:10 | ControlFlowNode for x [Dictionary element at key s] |
|
||||
| test.py:108:15:108:20 | ControlFlowNode for SOURCE | test.py:108:9:108:21 | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:109:10:109:10 | ControlFlowNode for x [Dictionary element at key s] | test.py:109:10:109:19 | ControlFlowNode for Attribute() |
|
||||
| test.py:234:11:234:16 | ControlFlowNode for SOURCE | test.py:234:11:234:17 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:234:11:234:17 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:234:10:234:21 | ControlFlowNode for Subscript |
|
||||
| test.py:237:10:237:17 | ControlFlowNode for List [List element] | test.py:237:10:237:20 | ControlFlowNode for Subscript |
|
||||
| test.py:237:11:237:16 | ControlFlowNode for SOURCE | test.py:237:10:237:17 | ControlFlowNode for List [List element] |
|
||||
| test.py:240:10:240:21 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:240:10:240:26 | ControlFlowNode for Subscript |
|
||||
| test.py:240:15:240:20 | ControlFlowNode for SOURCE | test.py:240:10:240:21 | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:258:28:258:33 | ControlFlowNode for SOURCE | test.py:258:10:258:34 | ControlFlowNode for second() |
|
||||
| test.py:317:12:317:17 | ControlFlowNode for SOURCE | test.py:317:10:317:18 | ControlFlowNode for f() |
|
||||
| test.py:321:28:321:33 | ControlFlowNode for SOURCE | test.py:321:10:321:34 | ControlFlowNode for second() |
|
||||
| test.py:82:9:82:37 | ControlFlowNode for ListComp [List element] | test.py:83:10:83:10 | ControlFlowNode for x [List element] |
|
||||
| test.py:82:10:82:15 | ControlFlowNode for SOURCE | test.py:82:9:82:37 | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:83:10:83:10 | ControlFlowNode for x [List element] | test.py:83:10:83:13 | ControlFlowNode for Subscript |
|
||||
| test.py:86:9:86:29 | ControlFlowNode for ListComp [List element] | test.py:87:10:87:10 | ControlFlowNode for x [List element] |
|
||||
| test.py:86:10:86:10 | ControlFlowNode for y | test.py:86:9:86:29 | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:86:16:86:16 | SSA variable y | test.py:86:10:86:10 | ControlFlowNode for y |
|
||||
| test.py:86:21:86:28 | ControlFlowNode for List [List element] | test.py:86:16:86:16 | SSA variable y |
|
||||
| test.py:86:22:86:27 | ControlFlowNode for SOURCE | test.py:86:21:86:28 | ControlFlowNode for List [List element] |
|
||||
| test.py:87:10:87:10 | ControlFlowNode for x [List element] | test.py:87:10:87:13 | ControlFlowNode for Subscript |
|
||||
| test.py:99:9:99:37 | ControlFlowNode for SetComp [Set element] | test.py:100:10:100:10 | ControlFlowNode for x [Set element] |
|
||||
| test.py:99:10:99:15 | ControlFlowNode for SOURCE | test.py:99:9:99:37 | ControlFlowNode for SetComp [Set element] |
|
||||
| test.py:100:10:100:10 | ControlFlowNode for x [Set element] | test.py:100:10:100:16 | ControlFlowNode for Attribute() |
|
||||
| test.py:103:9:103:29 | ControlFlowNode for SetComp [Set element] | test.py:104:10:104:10 | ControlFlowNode for x [Set element] |
|
||||
| test.py:103:10:103:10 | ControlFlowNode for y | test.py:103:9:103:29 | ControlFlowNode for SetComp [Set element] |
|
||||
| test.py:103:16:103:16 | SSA variable y | test.py:103:10:103:10 | ControlFlowNode for y |
|
||||
| test.py:103:21:103:28 | ControlFlowNode for List [List element] | test.py:103:16:103:16 | SSA variable y |
|
||||
| test.py:103:22:103:27 | ControlFlowNode for SOURCE | test.py:103:21:103:28 | ControlFlowNode for List [List element] |
|
||||
| test.py:104:10:104:10 | ControlFlowNode for x [Set element] | test.py:104:10:104:16 | ControlFlowNode for Attribute() |
|
||||
| test.py:112:9:112:21 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:113:10:113:10 | ControlFlowNode for x [Dictionary element at key s] |
|
||||
| test.py:112:15:112:20 | ControlFlowNode for SOURCE | test.py:112:9:112:21 | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:113:10:113:10 | ControlFlowNode for x [Dictionary element at key s] | test.py:113:10:113:15 | ControlFlowNode for Subscript |
|
||||
| test.py:116:9:116:21 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:117:10:117:10 | ControlFlowNode for x [Dictionary element at key s] |
|
||||
| test.py:116:15:116:20 | ControlFlowNode for SOURCE | test.py:116:9:116:21 | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:117:10:117:10 | ControlFlowNode for x [Dictionary element at key s] | test.py:117:10:117:19 | ControlFlowNode for Attribute() |
|
||||
| test.py:242:11:242:16 | ControlFlowNode for SOURCE | test.py:242:11:242:17 | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:242:11:242:17 | ControlFlowNode for Tuple [Tuple element at index 0] | test.py:242:10:242:21 | ControlFlowNode for Subscript |
|
||||
| test.py:245:10:245:17 | ControlFlowNode for List [List element] | test.py:245:10:245:20 | ControlFlowNode for Subscript |
|
||||
| test.py:245:11:245:16 | ControlFlowNode for SOURCE | test.py:245:10:245:17 | ControlFlowNode for List [List element] |
|
||||
| test.py:248:10:248:21 | ControlFlowNode for Dict [Dictionary element at key s] | test.py:248:10:248:26 | ControlFlowNode for Subscript |
|
||||
| test.py:248:15:248:20 | ControlFlowNode for SOURCE | test.py:248:10:248:21 | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:266:28:266:33 | ControlFlowNode for SOURCE | test.py:266:10:266:34 | ControlFlowNode for second() |
|
||||
| test.py:325:12:325:17 | ControlFlowNode for SOURCE | test.py:325:10:325:18 | ControlFlowNode for f() |
|
||||
| test.py:329:28:329:33 | ControlFlowNode for SOURCE | test.py:329:10:329:34 | ControlFlowNode for second() |
|
||||
nodes
|
||||
| test.py:24:10:24:26 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:24:21:24:26 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:25:9:25:9 | ControlFlowNode for x [Tuple element at index 1] | semmle.label | ControlFlowNode for x [Tuple element at index 1] |
|
||||
| test.py:25:9:25:12 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:26:10:26:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:35:9:35:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:36:10:36:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:40:9:40:16 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
|
||||
| test.py:41:10:41:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:44:9:44:17 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
|
||||
| test.py:45:10:45:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:48:9:48:10 | ControlFlowNode for IntegerLiteral | semmle.label | ControlFlowNode for IntegerLiteral |
|
||||
| datamodel.py:13:1:13:6 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
|
||||
| datamodel.py:13:10:13:17 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
|
||||
| datamodel.py:38:6:38:17 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() |
|
||||
| datamodel.py:38:6:38:17 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
|
||||
| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:65:1:65:1 | GSSA Variable c | semmle.label | GSSA Variable c |
|
||||
| datamodel.py:65:5:65:7 | ControlFlowNode for C() | semmle.label | ControlFlowNode for C() |
|
||||
| datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
|
||||
| datamodel.py:71:6:71:24 | GSSA Variable c | semmle.label | GSSA Variable c |
|
||||
| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:72:6:72:27 | GSSA Variable c | semmle.label | GSSA Variable c |
|
||||
| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:73:6:73:27 | ControlFlowNode for func_obj() | semmle.label | ControlFlowNode for func_obj() |
|
||||
| datamodel.py:73:6:73:27 | GSSA Variable c | semmle.label | GSSA Variable c |
|
||||
| datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:80:6:80:26 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
|
||||
| datamodel.py:80:6:80:26 | GSSA Variable c | semmle.label | GSSA Variable c |
|
||||
| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:81:6:81:26 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
|
||||
| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:82:6:82:26 | ControlFlowNode for c_func_obj() | semmle.label | ControlFlowNode for c_func_obj() |
|
||||
| datamodel.py:92:1:92:4 | GSSA Variable iter | semmle.label | GSSA Variable iter |
|
||||
| datamodel.py:92:8:92:21 | ControlFlowNode for gen() | semmle.label | ControlFlowNode for gen() |
|
||||
| datamodel.py:92:8:92:21 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
|
||||
| datamodel.py:93:6:93:20 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:93:6:93:20 | GSSA Variable iter | semmle.label | GSSA Variable iter |
|
||||
| datamodel.py:96:1:96:5 | GSSA Variable oiter | semmle.label | GSSA Variable oiter |
|
||||
| datamodel.py:96:9:96:24 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:96:9:96:24 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
|
||||
| datamodel.py:96:9:96:24 | GSSA Variable c | semmle.label | GSSA Variable c |
|
||||
| datamodel.py:97:6:97:21 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:97:6:97:21 | GSSA Variable oiter | semmle.label | GSSA Variable oiter |
|
||||
| datamodel.py:106:6:106:30 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:106:18:106:29 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
|
||||
| datamodel.py:107:6:107:32 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:107:18:107:31 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
|
||||
| datamodel.py:107:18:107:31 | GSSA Variable c | semmle.label | GSSA Variable c |
|
||||
| datamodel.py:119:6:119:30 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:119:18:119:29 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
|
||||
| test.py:32:10:32:26 | ControlFlowNode for Tuple [Tuple element at index 1] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 1] |
|
||||
| test.py:32:21:32:26 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:33:9:33:9 | ControlFlowNode for x [Tuple element at index 1] | semmle.label | ControlFlowNode for x [Tuple element at index 1] |
|
||||
| test.py:33:9:33:12 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:34:10:34:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:43:9:43:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:44:10:44:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:48:9:48:16 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
|
||||
| test.py:49:10:49:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:52:9:52:12 | ControlFlowNode for FloatLiteral | semmle.label | ControlFlowNode for FloatLiteral |
|
||||
| test.py:52:9:52:17 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
|
||||
| test.py:53:10:53:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:61:10:61:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:62:10:62:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:66:9:66:16 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:66:10:66:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:67:10:67:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
|
||||
| test.py:67:10:67:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:74:9:74:37 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:56:9:56:10 | ControlFlowNode for IntegerLiteral | semmle.label | ControlFlowNode for IntegerLiteral |
|
||||
| test.py:57:10:57:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:60:9:60:12 | ControlFlowNode for FloatLiteral | semmle.label | ControlFlowNode for FloatLiteral |
|
||||
| test.py:61:10:61:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:69:10:69:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:70:10:70:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
|
||||
| test.py:74:9:74:16 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:74:10:74:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:75:10:75:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
|
||||
| test.py:75:10:75:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:78:9:78:29 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:78:10:78:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:78:16:78:16 | SSA variable y | semmle.label | SSA variable y |
|
||||
| test.py:78:21:78:28 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:78:22:78:27 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:79:10:79:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
|
||||
| test.py:79:10:79:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:91:9:91:37 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] |
|
||||
| test.py:91:10:91:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:92:10:92:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] |
|
||||
| test.py:92:10:92:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:95:9:95:29 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] |
|
||||
| test.py:95:10:95:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:95:16:95:16 | SSA variable y | semmle.label | SSA variable y |
|
||||
| test.py:95:21:95:28 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:95:22:95:27 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:96:10:96:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] |
|
||||
| test.py:96:10:96:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:104:9:104:21 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:104:15:104:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:105:10:105:10 | ControlFlowNode for x [Dictionary element at key s] | semmle.label | ControlFlowNode for x [Dictionary element at key s] |
|
||||
| test.py:105:10:105:15 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:108:9:108:21 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:108:15:108:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:109:10:109:10 | ControlFlowNode for x [Dictionary element at key s] | semmle.label | ControlFlowNode for x [Dictionary element at key s] |
|
||||
| test.py:109:10:109:19 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:234:10:234:21 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:234:11:234:16 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:234:11:234:17 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:237:10:237:17 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:237:10:237:20 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:237:11:237:16 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:240:10:240:21 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:240:10:240:26 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:240:15:240:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:258:10:258:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
|
||||
| test.py:258:28:258:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:317:10:317:18 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() |
|
||||
| test.py:317:12:317:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:321:10:321:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
|
||||
| test.py:321:28:321:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:82:9:82:37 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:82:10:82:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:83:10:83:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
|
||||
| test.py:83:10:83:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:86:9:86:29 | ControlFlowNode for ListComp [List element] | semmle.label | ControlFlowNode for ListComp [List element] |
|
||||
| test.py:86:10:86:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:86:16:86:16 | SSA variable y | semmle.label | SSA variable y |
|
||||
| test.py:86:21:86:28 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:86:22:86:27 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:87:10:87:10 | ControlFlowNode for x [List element] | semmle.label | ControlFlowNode for x [List element] |
|
||||
| test.py:87:10:87:13 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:99:9:99:37 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] |
|
||||
| test.py:99:10:99:15 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:100:10:100:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] |
|
||||
| test.py:100:10:100:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:103:9:103:29 | ControlFlowNode for SetComp [Set element] | semmle.label | ControlFlowNode for SetComp [Set element] |
|
||||
| test.py:103:10:103:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
|
||||
| test.py:103:16:103:16 | SSA variable y | semmle.label | SSA variable y |
|
||||
| test.py:103:21:103:28 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:103:22:103:27 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:104:10:104:10 | ControlFlowNode for x [Set element] | semmle.label | ControlFlowNode for x [Set element] |
|
||||
| test.py:104:10:104:16 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:112:9:112:21 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:112:15:112:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:113:10:113:10 | ControlFlowNode for x [Dictionary element at key s] | semmle.label | ControlFlowNode for x [Dictionary element at key s] |
|
||||
| test.py:113:10:113:15 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:116:9:116:21 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:116:15:116:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:117:10:117:10 | ControlFlowNode for x [Dictionary element at key s] | semmle.label | ControlFlowNode for x [Dictionary element at key s] |
|
||||
| test.py:117:10:117:19 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| test.py:242:10:242:21 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:242:11:242:16 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:242:11:242:17 | ControlFlowNode for Tuple [Tuple element at index 0] | semmle.label | ControlFlowNode for Tuple [Tuple element at index 0] |
|
||||
| test.py:245:10:245:17 | ControlFlowNode for List [List element] | semmle.label | ControlFlowNode for List [List element] |
|
||||
| test.py:245:10:245:20 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:245:11:245:16 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:248:10:248:21 | ControlFlowNode for Dict [Dictionary element at key s] | semmle.label | ControlFlowNode for Dict [Dictionary element at key s] |
|
||||
| test.py:248:10:248:26 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
|
||||
| test.py:248:15:248:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:266:10:266:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
|
||||
| test.py:266:28:266:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:325:10:325:18 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() |
|
||||
| test.py:325:12:325:17 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:329:10:329:34 | ControlFlowNode for second() | semmle.label | ControlFlowNode for second() |
|
||||
| test.py:329:28:329:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
#select
|
||||
| test.py:26:10:26:10 | ControlFlowNode for y | test.py:24:21:24:26 | ControlFlowNode for SOURCE | test.py:26:10:26:10 | ControlFlowNode for y | <message> |
|
||||
| test.py:36:10:36:10 | ControlFlowNode for x | test.py:35:9:35:14 | ControlFlowNode for SOURCE | test.py:36:10:36:10 | ControlFlowNode for x | <message> |
|
||||
| test.py:41:10:41:10 | ControlFlowNode for x | test.py:40:9:40:16 | ControlFlowNode for Str | test.py:41:10:41:10 | ControlFlowNode for x | <message> |
|
||||
| test.py:45:10:45:10 | ControlFlowNode for x | test.py:44:9:44:17 | ControlFlowNode for Str | test.py:45:10:45:10 | ControlFlowNode for x | <message> |
|
||||
| test.py:49:10:49:10 | ControlFlowNode for x | test.py:48:9:48:10 | ControlFlowNode for IntegerLiteral | test.py:49:10:49:10 | ControlFlowNode for x | <message> |
|
||||
| test.py:53:10:53:10 | ControlFlowNode for x | test.py:52:9:52:12 | ControlFlowNode for FloatLiteral | test.py:53:10:53:10 | ControlFlowNode for x | <message> |
|
||||
| test.py:62:10:62:10 | ControlFlowNode for x | test.py:61:10:61:15 | ControlFlowNode for SOURCE | test.py:62:10:62:10 | ControlFlowNode for x | <message> |
|
||||
| test.py:67:10:67:13 | ControlFlowNode for Subscript | test.py:66:10:66:15 | ControlFlowNode for SOURCE | test.py:67:10:67:13 | ControlFlowNode for Subscript | <message> |
|
||||
| datamodel.py:38:6:38:17 | ControlFlowNode for f() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:38:6:38:17 | ControlFlowNode for f() | <message> |
|
||||
| datamodel.py:38:6:38:17 | ControlFlowNode for f() | datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() | <message> |
|
||||
| datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:73:6:73:27 | ControlFlowNode for func_obj() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:73:6:73:27 | ControlFlowNode for func_obj() | <message> |
|
||||
| datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:82:6:82:26 | ControlFlowNode for c_func_obj() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:82:6:82:26 | ControlFlowNode for c_func_obj() | <message> |
|
||||
| datamodel.py:93:6:93:20 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:93:6:93:20 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:97:6:97:21 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:97:6:97:21 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:106:6:106:30 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:106:6:106:30 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:107:6:107:32 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:107:6:107:32 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:119:6:119:30 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:119:6:119:30 | ControlFlowNode for Attribute() | <message> |
|
||||
| test.py:34:10:34:10 | ControlFlowNode for y | test.py:32:21:32:26 | ControlFlowNode for SOURCE | test.py:34:10:34:10 | ControlFlowNode for y | <message> |
|
||||
| test.py:44:10:44:10 | ControlFlowNode for x | test.py:43:9:43:14 | ControlFlowNode for SOURCE | test.py:44:10:44:10 | ControlFlowNode for x | <message> |
|
||||
| test.py:49:10:49:10 | ControlFlowNode for x | test.py:48:9:48:16 | ControlFlowNode for Str | test.py:49:10:49:10 | ControlFlowNode for x | <message> |
|
||||
| test.py:53:10:53:10 | ControlFlowNode for x | test.py:52:9:52:17 | ControlFlowNode for Str | test.py:53:10:53:10 | ControlFlowNode for x | <message> |
|
||||
| test.py:57:10:57:10 | ControlFlowNode for x | test.py:56:9:56:10 | ControlFlowNode for IntegerLiteral | test.py:57:10:57:10 | ControlFlowNode for x | <message> |
|
||||
| test.py:61:10:61:10 | ControlFlowNode for x | test.py:60:9:60:12 | ControlFlowNode for FloatLiteral | test.py:61:10:61:10 | ControlFlowNode for x | <message> |
|
||||
| test.py:70:10:70:10 | ControlFlowNode for x | test.py:69:10:69:15 | ControlFlowNode for SOURCE | test.py:70:10:70:10 | ControlFlowNode for x | <message> |
|
||||
| test.py:75:10:75:13 | ControlFlowNode for Subscript | test.py:74:10:74:15 | ControlFlowNode for SOURCE | test.py:75:10:75:13 | ControlFlowNode for Subscript | <message> |
|
||||
| test.py:79:10:79:13 | ControlFlowNode for Subscript | test.py:78:22:78:27 | ControlFlowNode for SOURCE | test.py:79:10:79:13 | ControlFlowNode for Subscript | <message> |
|
||||
| test.py:92:10:92:16 | ControlFlowNode for Attribute() | test.py:91:10:91:15 | ControlFlowNode for SOURCE | test.py:92:10:92:16 | ControlFlowNode for Attribute() | <message> |
|
||||
| test.py:96:10:96:16 | ControlFlowNode for Attribute() | test.py:95:22:95:27 | ControlFlowNode for SOURCE | test.py:96:10:96:16 | ControlFlowNode for Attribute() | <message> |
|
||||
| test.py:105:10:105:15 | ControlFlowNode for Subscript | test.py:104:15:104:20 | ControlFlowNode for SOURCE | test.py:105:10:105:15 | ControlFlowNode for Subscript | <message> |
|
||||
| test.py:109:10:109:19 | ControlFlowNode for Attribute() | test.py:108:15:108:20 | ControlFlowNode for SOURCE | test.py:109:10:109:19 | ControlFlowNode for Attribute() | <message> |
|
||||
| test.py:234:10:234:21 | ControlFlowNode for Subscript | test.py:234:11:234:16 | ControlFlowNode for SOURCE | test.py:234:10:234:21 | ControlFlowNode for Subscript | <message> |
|
||||
| test.py:237:10:237:20 | ControlFlowNode for Subscript | test.py:237:11:237:16 | ControlFlowNode for SOURCE | test.py:237:10:237:20 | ControlFlowNode for Subscript | <message> |
|
||||
| test.py:240:10:240:26 | ControlFlowNode for Subscript | test.py:240:15:240:20 | ControlFlowNode for SOURCE | test.py:240:10:240:26 | ControlFlowNode for Subscript | <message> |
|
||||
| test.py:258:10:258:34 | ControlFlowNode for second() | test.py:258:28:258:33 | ControlFlowNode for SOURCE | test.py:258:10:258:34 | ControlFlowNode for second() | <message> |
|
||||
| test.py:317:10:317:18 | ControlFlowNode for f() | test.py:317:12:317:17 | ControlFlowNode for SOURCE | test.py:317:10:317:18 | ControlFlowNode for f() | <message> |
|
||||
| test.py:321:10:321:34 | ControlFlowNode for second() | test.py:321:28:321:33 | ControlFlowNode for SOURCE | test.py:321:10:321:34 | ControlFlowNode for second() | <message> |
|
||||
| test.py:83:10:83:13 | ControlFlowNode for Subscript | test.py:82:10:82:15 | ControlFlowNode for SOURCE | test.py:83:10:83:13 | ControlFlowNode for Subscript | <message> |
|
||||
| test.py:87:10:87:13 | ControlFlowNode for Subscript | test.py:86:22:86:27 | ControlFlowNode for SOURCE | test.py:87:10:87:13 | ControlFlowNode for Subscript | <message> |
|
||||
| test.py:100:10:100:16 | ControlFlowNode for Attribute() | test.py:99:10:99:15 | ControlFlowNode for SOURCE | test.py:100:10:100:16 | ControlFlowNode for Attribute() | <message> |
|
||||
| test.py:104:10:104:16 | ControlFlowNode for Attribute() | test.py:103:22:103:27 | ControlFlowNode for SOURCE | test.py:104:10:104:16 | ControlFlowNode for Attribute() | <message> |
|
||||
| test.py:113:10:113:15 | ControlFlowNode for Subscript | test.py:112:15:112:20 | ControlFlowNode for SOURCE | test.py:113:10:113:15 | ControlFlowNode for Subscript | <message> |
|
||||
| test.py:117:10:117:19 | ControlFlowNode for Attribute() | test.py:116:15:116:20 | ControlFlowNode for SOURCE | test.py:117:10:117:19 | ControlFlowNode for Attribute() | <message> |
|
||||
| test.py:242:10:242:21 | ControlFlowNode for Subscript | test.py:242:11:242:16 | ControlFlowNode for SOURCE | test.py:242:10:242:21 | ControlFlowNode for Subscript | <message> |
|
||||
| test.py:245:10:245:20 | ControlFlowNode for Subscript | test.py:245:11:245:16 | ControlFlowNode for SOURCE | test.py:245:10:245:20 | ControlFlowNode for Subscript | <message> |
|
||||
| test.py:248:10:248:26 | ControlFlowNode for Subscript | test.py:248:15:248:20 | ControlFlowNode for SOURCE | test.py:248:10:248:26 | ControlFlowNode for Subscript | <message> |
|
||||
| test.py:266:10:266:34 | ControlFlowNode for second() | test.py:266:28:266:33 | ControlFlowNode for SOURCE | test.py:266:10:266:34 | ControlFlowNode for second() | <message> |
|
||||
| test.py:325:10:325:18 | ControlFlowNode for f() | test.py:325:12:325:17 | ControlFlowNode for SOURCE | test.py:325:10:325:18 | ControlFlowNode for f() | <message> |
|
||||
| test.py:329:10:329:34 | ControlFlowNode for second() | test.py:329:28:329:33 | ControlFlowNode for SOURCE | test.py:329:10:329:34 | ControlFlowNode for second() | <message> |
|
||||
|
||||
159
python/ql/test/experimental/dataflow/coverage/datamodel.py
Normal file
159
python/ql/test/experimental/dataflow/coverage/datamodel.py
Normal file
@@ -0,0 +1,159 @@
|
||||
# User-defined methods, both instance methods and class methods, can be called in many non-standard ways
|
||||
# i.e. differently from simply `c.f()` or `C.f()`. For example, a user-defined `__await__` method on a
|
||||
# class `C` will be called by the syntactic construct `await c` when `c` is an instance of `C`.
|
||||
#
|
||||
# These tests are based on the first part of https://docs.python.org/3/reference/datamodel.html.
|
||||
# A thorough covering of methods in that document is found in classes.py.
|
||||
#
|
||||
# Intended sources should be the variable `SOURCE` and intended sinks should be
|
||||
# arguments to the function `SINK` (see python/ql/test/experimental/dataflow/testConfig.qll).
|
||||
|
||||
# These are defined so that we can evaluate the test code.
|
||||
NONSOURCE = "not a source"
|
||||
SOURCE = "source"
|
||||
|
||||
def is_source(x):
|
||||
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
|
||||
|
||||
def SINK(x):
|
||||
if is_source(x):
|
||||
print("OK")
|
||||
else:
|
||||
print("Unexpected flow", x)
|
||||
|
||||
def SINK_F(x):
|
||||
if is_source(x):
|
||||
print("Unexpected flow", x)
|
||||
else:
|
||||
print("OK")
|
||||
|
||||
# Callable types
|
||||
# These are the types to which the function call operation (see section Calls) can be applied:
|
||||
|
||||
# User-defined functions
|
||||
# A user-defined function object is created by a function definition (see section Function definitions). It should be called with an argument list containing the same number of items as the function's formal parameter list.
|
||||
def f(a, b):
|
||||
return a
|
||||
|
||||
SINK(f(SOURCE, 3))
|
||||
|
||||
# Instance methods
|
||||
# An instance method object combines a class, a class instance and any callable object (normally a user-defined function).
|
||||
class C(object):
|
||||
|
||||
def method(self, x, cls):
|
||||
assert cls is self.__class__
|
||||
return x
|
||||
|
||||
@classmethod
|
||||
def classmethod(cls, x):
|
||||
return x
|
||||
|
||||
@staticmethod
|
||||
def staticmethod(x):
|
||||
return x
|
||||
|
||||
def gen(self, x, count):
|
||||
n = count
|
||||
while n > 0:
|
||||
yield x
|
||||
n -= 1
|
||||
|
||||
async def coro(self, x):
|
||||
return x
|
||||
|
||||
c = C()
|
||||
|
||||
# When an instance method object is created by retrieving a user-defined function object from a class via one of its instances, its __self__ attribute is the instance, and the method object is said to be bound. The new method’s __func__ attribute is the original function object.
|
||||
func_obj = c.method.__func__
|
||||
|
||||
# When an instance method object is called, the underlying function (__func__) is called, inserting the class instance (__self__) in front of the argument list. For instance, when C is a class which contains a definition for a function f(), and x is an instance of C, calling x.f(1) is equivalent to calling C.f(x, 1).
|
||||
SINK(c.method(SOURCE, C))
|
||||
SINK(C.method(c, SOURCE, C))
|
||||
SINK(func_obj(c, SOURCE, C))
|
||||
|
||||
|
||||
# When an instance method object is created by retrieving a class method object from a class or instance, its __self__ attribute is the class itself, and its __func__ attribute is the function object underlying the class method.
|
||||
c_func_obj = C.classmethod.__func__
|
||||
|
||||
# When an instance method object is derived from a class method object, the “class instance” stored in __self__ will actually be the class itself, so that calling either x.f(1) or C.f(1) is equivalent to calling f(C,1) where f is the underlying function.
|
||||
SINK(c.classmethod(SOURCE))
|
||||
SINK(C.classmethod(SOURCE))
|
||||
SINK(c_func_obj(C, SOURCE))
|
||||
|
||||
# Generator functions
|
||||
# A function or method which uses the yield statement (see section The yield statement) is called a generator function. Such a function, when called, always returns an iterator object which can be used to execute the body of the function: calling the iterator’s iterator.__next__() method will cause the function to execute until it provides a value using the yield statement. When the function executes a return statement or falls off the end, a StopIteration exception is raised and the iterator will have reached the end of the set of values to be returned.
|
||||
def gen(x, count):
|
||||
n = count
|
||||
while n > 0:
|
||||
yield x
|
||||
n -= 1
|
||||
|
||||
iter = gen(SOURCE, 1)
|
||||
SINK(iter.__next__())
|
||||
# SINK_F(iter.__next__()) # throws StopIteration, FP
|
||||
|
||||
oiter = c.gen(SOURCE, 1)
|
||||
SINK(oiter.__next__())
|
||||
# SINK_F(oiter.__next__()) # throws StopIteration, FP
|
||||
|
||||
# Coroutine functions
|
||||
# A function or method which is defined using async def is called a coroutine function. Such a function, when called, returns a coroutine object. It may contain await expressions, as well as async with and async for statements. See also the Coroutine Objects section.
|
||||
async def coro(x):
|
||||
return x
|
||||
|
||||
import asyncio
|
||||
SINK(asyncio.run(coro(SOURCE)))
|
||||
SINK(asyncio.run(c.coro(SOURCE)))
|
||||
|
||||
class A:
|
||||
|
||||
def __await__(self):
|
||||
# yield SOURCE -- see https://groups.google.com/g/dev-python/c/_lrrc-vp9TI?pli=1
|
||||
return (yield from asyncio.coroutine(lambda: SOURCE)())
|
||||
|
||||
async def agen(x):
|
||||
a = A()
|
||||
return await a
|
||||
|
||||
SINK(asyncio.run(agen(SOURCE)))
|
||||
|
||||
# Asynchronous generator functions
|
||||
# A function or method which is defined using async def and which uses the yield statement is called a asynchronous generator function. Such a function, when called, returns an asynchronous iterator object which can be used in an async for statement to execute the body of the function.
|
||||
|
||||
# Calling the asynchronous iterator’s aiterator.__anext__() method will return an awaitable which when awaited will execute until it provides a value using the yield expression. When the function executes an empty return statement or falls off the end, a StopAsyncIteration exception is raised and the asynchronous iterator will have reached the end of the set of values to be yielded.
|
||||
|
||||
# Built-in functions
|
||||
# A built-in function object is a wrapper around a C function. Examples of built-in functions are len() and math.sin() (math is a standard built-in module). The number and type of the arguments are determined by the C function. Special read-only attributes: __doc__ is the function’s documentation string, or None if unavailable; __name__ is the function’s name; __self__ is set to None (but see the next item); __module__ is the name of the module the function was defined in or None if unavailable.
|
||||
|
||||
# Built-in methods
|
||||
# This is really a different disguise of a built-in function, this time containing an object passed to the C function as an implicit extra argument. An example of a built-in method is alist.append(), assuming alist is a list object. In this case, the special read-only attribute __self__ is set to the object denoted by alist.
|
||||
|
||||
# Classes
|
||||
# Classes are callable. These objects normally act as factories for new instances of themselves, but variations are possible for class types that override __new__(). The arguments of the call are passed to __new__() and, in the typical case, to __init__() to initialize the new instance.
|
||||
|
||||
# Class Instances
|
||||
# Instances of arbitrary classes can be made callable by defining a __call__() method in their class.
|
||||
|
||||
# If a class sets __iter__() to None, calling iter() on its instances will raise a TypeError (without falling back to __getitem__()).
|
||||
|
||||
# 3.3.1. Basic customization
|
||||
|
||||
class Customized:
|
||||
|
||||
a = NONSOURCE
|
||||
b = NONSOURCE
|
||||
|
||||
def __new__(cls):
|
||||
cls.a = SOURCE
|
||||
return super().__new__(cls)
|
||||
|
||||
def __init__(self):
|
||||
self.b = SOURCE
|
||||
|
||||
# testing __new__ and __init__
|
||||
customized = Customized()
|
||||
SINK(Customized.a)
|
||||
SINK_F(Customized.b)
|
||||
SINK(customized.a)
|
||||
SINK(customized.b)
|
||||
@@ -1,7 +1,7 @@
|
||||
| test.py:24:5:24:5 | SSA variable x | test.py:23:1:23:33 | Exit node for Function test_tuple_with_local_flow |
|
||||
| test.py:24:5:24:5 | SSA variable x | test.py:25:9:25:9 | ControlFlowNode for x |
|
||||
| test.py:24:10:24:26 | ControlFlowNode for Tuple | test.py:24:5:24:5 | SSA variable x |
|
||||
| test.py:25:5:25:5 | SSA variable y | test.py:26:5:26:11 | SSA variable y |
|
||||
| test.py:25:5:25:5 | SSA variable y | test.py:26:10:26:10 | ControlFlowNode for y |
|
||||
| test.py:25:9:25:12 | ControlFlowNode for Subscript | test.py:25:5:25:5 | SSA variable y |
|
||||
| test.py:26:5:26:11 | SSA variable y | test.py:23:1:23:33 | Exit node for Function test_tuple_with_local_flow |
|
||||
| test.py:32:5:32:5 | SSA variable x | test.py:31:1:31:33 | Exit node for Function test_tuple_with_local_flow |
|
||||
| test.py:32:5:32:5 | SSA variable x | test.py:33:9:33:9 | ControlFlowNode for x |
|
||||
| test.py:32:10:32:26 | ControlFlowNode for Tuple | test.py:32:5:32:5 | SSA variable x |
|
||||
| test.py:33:5:33:5 | SSA variable y | test.py:34:5:34:11 | SSA variable y |
|
||||
| test.py:33:5:33:5 | SSA variable y | test.py:34:10:34:10 | ControlFlowNode for y |
|
||||
| test.py:33:9:33:12 | ControlFlowNode for Subscript | test.py:33:5:33:5 | SSA variable y |
|
||||
| test.py:34:5:34:11 | SSA variable y | test.py:31:1:31:33 | Exit node for Function test_tuple_with_local_flow |
|
||||
|
||||
@@ -6,19 +6,27 @@
|
||||
#
|
||||
# Functions whose name ends with "_with_local_flow" will also be tested for local flow.
|
||||
#
|
||||
# All functions starting with "test_" should run and either
|
||||
# - print a source (sources are defined in testConfig.qll).
|
||||
# - print "Unexpected flow: " and a non-source
|
||||
# (The idea is to later write a script to autimatically confirm this.)
|
||||
# All functions starting with "test_" should run and print `"OK"`.
|
||||
# This can be checked by running validTest.py.
|
||||
|
||||
# These are defined so that we can evaluate the test code.
|
||||
NONSOURCE = "not a source"
|
||||
SOURCE = "source"
|
||||
|
||||
def is_source(x):
|
||||
return x == "source" or x == b"source" or x == 42 or x == 42.0 or x == 42j
|
||||
|
||||
def SINK(x):
|
||||
print(x)
|
||||
if is_source(x):
|
||||
print("OK")
|
||||
else:
|
||||
print("Unexpected flow", x)
|
||||
|
||||
def SINK_F(x):
|
||||
print("Unexpected flow: ", x)
|
||||
if is_source(x):
|
||||
print("Unexpected flow", x)
|
||||
else:
|
||||
print("OK")
|
||||
|
||||
def test_tuple_with_local_flow():
|
||||
x = (NONSOURCE, SOURCE)
|
||||
|
||||
49
python/ql/test/experimental/dataflow/coverage/validTest.py
Normal file
49
python/ql/test/experimental/dataflow/coverage/validTest.py
Normal file
@@ -0,0 +1,49 @@
|
||||
def check_output(s, f):
|
||||
if s == "OK\n":
|
||||
pass
|
||||
else:
|
||||
raise RuntimeError("Function failed", s, f)
|
||||
|
||||
def check_test_function(f):
|
||||
from io import StringIO
|
||||
import sys
|
||||
|
||||
capturer = StringIO()
|
||||
old_stdout = sys.stdout
|
||||
sys.stdout = capturer
|
||||
f()
|
||||
sys.stdout = old_stdout
|
||||
check_output(capturer.getvalue(), f)
|
||||
|
||||
def check_async_test_function(f):
|
||||
from io import StringIO
|
||||
import sys
|
||||
import asyncio
|
||||
|
||||
capturer = StringIO()
|
||||
old_stdout = sys.stdout
|
||||
sys.stdout = capturer
|
||||
asyncio.run(f())
|
||||
sys.stdout = old_stdout
|
||||
check_output(capturer.getvalue(), f)
|
||||
|
||||
def check_tests_valid(testFile):
|
||||
import importlib
|
||||
tests = importlib.import_module(testFile)
|
||||
for i in dir(tests):
|
||||
# print("Considering", i)
|
||||
if i.startswith("test_"):
|
||||
item = getattr(tests,i)
|
||||
if callable(item):
|
||||
print("Checking", testFile, item)
|
||||
check_test_function(item)
|
||||
|
||||
elif i.startswith("atest_"):
|
||||
item = getattr(tests,i)
|
||||
if callable(item):
|
||||
print("Checking", testFile, item)
|
||||
check_async_test_function(item)
|
||||
|
||||
if __name__ == '__main__':
|
||||
check_tests_valid("classes")
|
||||
check_tests_valid("test")
|
||||
@@ -1,2 +1,3 @@
|
||||
| imports_test.py:21:1:21:20 | from module import * | Using 'from ... import *' pollutes the namespace |
|
||||
| imports_test.py:22:1:22:32 | from module_without_all import * | Using 'from ... import *' pollutes the namespace |
|
||||
| imports_test.py:65:1:65:40 | from module_that_does_not_exist import * | Using 'from ... import *' pollutes the namespace |
|
||||
|
||||
@@ -61,3 +61,5 @@ import module1 as different
|
||||
#Use it
|
||||
different
|
||||
|
||||
# FP reported in https://github.com/github/codeql/issues/4003
|
||||
from module_that_does_not_exist import *
|
||||
|
||||
Reference in New Issue
Block a user