mirror of
https://github.com/github/codeql.git
synced 2026-04-27 17:55:19 +02:00
Merge branch 'main' of https://github.com/github/codeql into python/remove-ssa-nodes-from-dataflow-graph
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
// TODO: this should be promoted to be a REAL consistency query by being placed in
|
||||
// `python/ql/consistency-queries`. For for now it resides here.
|
||||
import python
|
||||
import semmle.python.dataflow.new.DataFlow::DataFlow
|
||||
import semmle.python.dataflow.new.internal.DataFlowPrivate
|
||||
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -5,6 +5,7 @@ import functools
|
||||
sys.path.append(os.path.dirname(os.path.dirname((__file__))))
|
||||
from testlib import expects
|
||||
|
||||
SOURCE = "source"
|
||||
arg = "source"
|
||||
arg1 = "source1"
|
||||
arg2 = "source2"
|
||||
@@ -269,3 +270,68 @@ def test_stararg_mixed():
|
||||
starargs_mixed(arg1, *args, *empty_args) # $ arg1
|
||||
args = (arg2, "safe")
|
||||
starargs_mixed(arg1, *empty_args, *args) # $ arg1 MISSING: arg2
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Test updating field of argument
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
class MyClass: pass
|
||||
|
||||
def kwargsSideEffect(**kwargs):
|
||||
kwargs["a"].foo = kwargs["b"]
|
||||
|
||||
@expects(2)
|
||||
def test_kwargsSideEffect():
|
||||
a = MyClass()
|
||||
kwargs = {"a": a, "b": SOURCE}
|
||||
kwargsSideEffect(**kwargs)
|
||||
SINK(a.foo) # $ MISSING: flow
|
||||
|
||||
a = MyClass()
|
||||
kwargsSideEffect(a=a, b=SOURCE)
|
||||
SINK(a.foo) # $ MISSING: flow
|
||||
|
||||
|
||||
def keywordArgSideEffect(a, b):
|
||||
a.foo = b
|
||||
|
||||
@expects(2)
|
||||
def test_keywordArgSideEffect():
|
||||
a = MyClass()
|
||||
kwargs = {"a": a, "b": SOURCE}
|
||||
keywordArgSideEffect(**kwargs)
|
||||
SINK(a.foo) # $ MISSING: flow
|
||||
|
||||
a = MyClass()
|
||||
keywordArgSideEffect(a=a, b=SOURCE)
|
||||
SINK(a.foo) # $ flow="SOURCE, l:-1 -> a.foo"
|
||||
|
||||
|
||||
def starargsSideEffect(*args):
|
||||
args[0].foo = args[1]
|
||||
|
||||
@expects(2)
|
||||
def test_starargsSideEffect():
|
||||
a = MyClass()
|
||||
args = (a, SOURCE)
|
||||
starargsSideEffect(*args)
|
||||
SINK(a.foo) # $ MISSING: flow
|
||||
|
||||
a = MyClass()
|
||||
starargsSideEffect(a, SOURCE)
|
||||
SINK(a.foo) # $ MISSING: flow
|
||||
|
||||
|
||||
def positionalArgSideEffect(a, b):
|
||||
a.foo = b
|
||||
|
||||
@expects(2)
|
||||
def test_positionalArgSideEffect():
|
||||
a = MyClass()
|
||||
args = (a, SOURCE)
|
||||
positionalArgSideEffect(*args)
|
||||
SINK(a.foo) # $ MISSING: flow
|
||||
|
||||
a = MyClass()
|
||||
positionalArgSideEffect(a, SOURCE)
|
||||
SINK(a.foo) # $ flow="SOURCE, l:-1 -> a.foo"
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -0,0 +1,31 @@
|
||||
def_count
|
||||
| 4 |
|
||||
def
|
||||
| def_use_flow.py:10:5:10:5 | Essa node definition |
|
||||
| def_use_flow.py:17:11:17:11 | Essa node definition |
|
||||
| def_use_flow.py:19:9:19:9 | Essa node definition |
|
||||
| def_use_flow.py:21:7:21:7 | Essa node definition |
|
||||
implicit_use_count
|
||||
| 0 |
|
||||
implicit_use
|
||||
source_use_count
|
||||
| 3 |
|
||||
source_use
|
||||
| def_use_flow.py:28:15:28:15 | ControlFlowNode for x |
|
||||
| def_use_flow.py:30:13:30:13 | ControlFlowNode for x |
|
||||
| def_use_flow.py:32:11:32:11 | ControlFlowNode for x |
|
||||
def_use_edge_count
|
||||
| 12 |
|
||||
def_use_edge
|
||||
| def_use_flow.py:10:5:10:5 | SSA variable x | def_use_flow.py:28:15:28:15 | ControlFlowNode for x |
|
||||
| def_use_flow.py:10:5:10:5 | SSA variable x | def_use_flow.py:30:13:30:13 | ControlFlowNode for x |
|
||||
| def_use_flow.py:10:5:10:5 | SSA variable x | def_use_flow.py:32:11:32:11 | ControlFlowNode for x |
|
||||
| def_use_flow.py:17:11:17:11 | SSA variable x | def_use_flow.py:28:15:28:15 | ControlFlowNode for x |
|
||||
| def_use_flow.py:17:11:17:11 | SSA variable x | def_use_flow.py:30:13:30:13 | ControlFlowNode for x |
|
||||
| def_use_flow.py:17:11:17:11 | SSA variable x | def_use_flow.py:32:11:32:11 | ControlFlowNode for x |
|
||||
| def_use_flow.py:19:9:19:9 | SSA variable x | def_use_flow.py:28:15:28:15 | ControlFlowNode for x |
|
||||
| def_use_flow.py:19:9:19:9 | SSA variable x | def_use_flow.py:30:13:30:13 | ControlFlowNode for x |
|
||||
| def_use_flow.py:19:9:19:9 | SSA variable x | def_use_flow.py:32:11:32:11 | ControlFlowNode for x |
|
||||
| def_use_flow.py:21:7:21:7 | SSA variable x | def_use_flow.py:28:15:28:15 | ControlFlowNode for x |
|
||||
| def_use_flow.py:21:7:21:7 | SSA variable x | def_use_flow.py:30:13:30:13 | ControlFlowNode for x |
|
||||
| def_use_flow.py:21:7:21:7 | SSA variable x | def_use_flow.py:32:11:32:11 | ControlFlowNode for x |
|
||||
@@ -0,0 +1,47 @@
|
||||
import python
|
||||
private import semmle.python.dataflow.new.internal.DataFlowPrivate
|
||||
|
||||
query int def_count() {
|
||||
exists(SsaSourceVariable x | x.getName() = "x" |
|
||||
result = count(EssaNodeDefinition def | def.getSourceVariable() = x)
|
||||
)
|
||||
}
|
||||
|
||||
query EssaNodeDefinition def() {
|
||||
exists(SsaSourceVariable x | x.getName() = "x" | result.getSourceVariable() = x)
|
||||
}
|
||||
|
||||
query int implicit_use_count() {
|
||||
exists(SsaSourceVariable x | x.getName() = "x" | result = count(x.getAnImplicitUse()))
|
||||
}
|
||||
|
||||
query ControlFlowNode implicit_use() {
|
||||
exists(SsaSourceVariable x | x.getName() = "x" | result = x.getAnImplicitUse())
|
||||
}
|
||||
|
||||
query int source_use_count() {
|
||||
exists(SsaSourceVariable x | x.getName() = "x" | result = count(x.getASourceUse()))
|
||||
}
|
||||
|
||||
query ControlFlowNode source_use() {
|
||||
exists(SsaSourceVariable x | x.getName() = "x" | result = x.getASourceUse())
|
||||
}
|
||||
|
||||
query int def_use_edge_count() {
|
||||
exists(SsaSourceVariable x | x.getName() = "x" |
|
||||
result =
|
||||
count(EssaVariable v, NameNode use |
|
||||
v.getSourceVariable() = x and
|
||||
use = x.getAUse() and
|
||||
LocalFlow::defToFirstUse(v, use)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
query predicate def_use_edge(EssaVariable v, NameNode use) {
|
||||
exists(SsaSourceVariable x | x.getName() = "x" |
|
||||
v.getSourceVariable() = x and
|
||||
use = x.getAUse() and
|
||||
LocalFlow::defToFirstUse(v, use)
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
# This test file is inspired by
|
||||
# `csharp/ql/test/library-tests/dataflow/local/UseUseExplosion.cs`
|
||||
# but with `n=3` kept small, since we do have the explosion.
|
||||
|
||||
cond = ...
|
||||
|
||||
# global variables are slightly special,
|
||||
# so we go into a function scope
|
||||
def scope():
|
||||
x = 0
|
||||
|
||||
if(cond > 3):
|
||||
if(cond > 2):
|
||||
if(cond > 1):
|
||||
pass
|
||||
else:
|
||||
x = 1
|
||||
else:
|
||||
x = 2
|
||||
else:
|
||||
x = 3
|
||||
|
||||
if(cond > 3):
|
||||
if(cond > 2):
|
||||
if(cond > 1):
|
||||
pass
|
||||
else:
|
||||
use(x)
|
||||
else:
|
||||
use(x)
|
||||
else:
|
||||
use(x)
|
||||
|
||||
def use(v):
|
||||
# this could just be `pass` but we do not want it optimized away.
|
||||
y = v+2
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -0,0 +1 @@
|
||||
# an empty file, since we want the test to run on an empty db
|
||||
@@ -0,0 +1,8 @@
|
||||
import python
|
||||
import semmle.python.dataflow.new.FlowSummary
|
||||
import semmle.python.dataflow.new.internal.FlowSummaryImpl
|
||||
|
||||
query predicate invalidSpecComponent(SummarizedCallable sc, string s, string c) {
|
||||
(sc.propagatesFlowExt(s, _, _) or sc.propagatesFlowExt(_, s, _)) and
|
||||
Private::External::invalidSpecComponent(s, c)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import python
|
||||
import semmle.python.dataflow.new.FlowSummary
|
||||
import semmle.python.dataflow.new.internal.FlowSummaryImpl
|
||||
|
||||
from SummarizedCallable sc, string s, string c, string attr
|
||||
where
|
||||
(sc.propagatesFlowExt(s, _, _) or sc.propagatesFlowExt(_, s, _)) and
|
||||
Private::External::invalidSpecComponent(s, c) and
|
||||
c = "Attribute[" + attr + "]"
|
||||
select "The attribute \"" + attr +
|
||||
"\" is not a valid TAttributeContent, please add it to the hardcoded list of TAttributeContent in the dataflow library."
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
@@ -0,0 +1,36 @@
|
||||
# This test file is inspired by
|
||||
# `csharp/ql/test/library-tests/dataflow/local/UseUseExplosion.cs`
|
||||
# but with `n=3` kept small, since we do have the explosion.
|
||||
|
||||
cond = ...
|
||||
|
||||
# global variables are slightly special,
|
||||
# so we go into a function scope
|
||||
def scope():
|
||||
x = 0
|
||||
|
||||
if(cond > 3):
|
||||
if(cond > 2):
|
||||
if(cond > 1):
|
||||
pass
|
||||
else:
|
||||
use(x)
|
||||
else:
|
||||
use(x)
|
||||
else:
|
||||
use(x)
|
||||
|
||||
if(cond > 3):
|
||||
if(cond > 2):
|
||||
if(cond > 1):
|
||||
pass
|
||||
else:
|
||||
use(x)
|
||||
else:
|
||||
use(x)
|
||||
else:
|
||||
use(x)
|
||||
|
||||
def use(v):
|
||||
# this could just be `pass` but we do not want it optimized away.
|
||||
y = v+2
|
||||
@@ -0,0 +1,24 @@
|
||||
implicit_use_count
|
||||
| 0 |
|
||||
implicit_use
|
||||
source_use_count
|
||||
| 6 |
|
||||
source_use
|
||||
| read_explosion.py:17:15:17:15 | ControlFlowNode for x |
|
||||
| read_explosion.py:19:13:19:13 | ControlFlowNode for x |
|
||||
| read_explosion.py:21:11:21:11 | ControlFlowNode for x |
|
||||
| read_explosion.py:28:15:28:15 | ControlFlowNode for x |
|
||||
| read_explosion.py:30:13:30:13 | ControlFlowNode for x |
|
||||
| read_explosion.py:32:11:32:11 | ControlFlowNode for x |
|
||||
use_use_edge_count
|
||||
| 9 |
|
||||
use_use_edge
|
||||
| read_explosion.py:17:15:17:15 | ControlFlowNode for x | read_explosion.py:28:15:28:15 | ControlFlowNode for x |
|
||||
| read_explosion.py:17:15:17:15 | ControlFlowNode for x | read_explosion.py:30:13:30:13 | ControlFlowNode for x |
|
||||
| read_explosion.py:17:15:17:15 | ControlFlowNode for x | read_explosion.py:32:11:32:11 | ControlFlowNode for x |
|
||||
| read_explosion.py:19:13:19:13 | ControlFlowNode for x | read_explosion.py:28:15:28:15 | ControlFlowNode for x |
|
||||
| read_explosion.py:19:13:19:13 | ControlFlowNode for x | read_explosion.py:30:13:30:13 | ControlFlowNode for x |
|
||||
| read_explosion.py:19:13:19:13 | ControlFlowNode for x | read_explosion.py:32:11:32:11 | ControlFlowNode for x |
|
||||
| read_explosion.py:21:11:21:11 | ControlFlowNode for x | read_explosion.py:28:15:28:15 | ControlFlowNode for x |
|
||||
| read_explosion.py:21:11:21:11 | ControlFlowNode for x | read_explosion.py:30:13:30:13 | ControlFlowNode for x |
|
||||
| read_explosion.py:21:11:21:11 | ControlFlowNode for x | read_explosion.py:32:11:32:11 | ControlFlowNode for x |
|
||||
@@ -0,0 +1,37 @@
|
||||
import python
|
||||
private import semmle.python.dataflow.new.internal.DataFlowPrivate
|
||||
|
||||
query int implicit_use_count() {
|
||||
exists(SsaSourceVariable x | x.getName() = "x" | result = count(x.getAnImplicitUse()))
|
||||
}
|
||||
|
||||
query ControlFlowNode implicit_use() {
|
||||
exists(SsaSourceVariable x | x.getName() = "x" | result = x.getAnImplicitUse())
|
||||
}
|
||||
|
||||
query int source_use_count() {
|
||||
exists(SsaSourceVariable x | x.getName() = "x" | result = count(x.getASourceUse()))
|
||||
}
|
||||
|
||||
query ControlFlowNode source_use() {
|
||||
exists(SsaSourceVariable x | x.getName() = "x" | result = x.getASourceUse())
|
||||
}
|
||||
|
||||
query int use_use_edge_count() {
|
||||
exists(SsaSourceVariable x | x.getName() = "x" |
|
||||
result =
|
||||
count(NameNode use1, NameNode use2 |
|
||||
use1 = x.getAUse() and
|
||||
use2 = x.getAUse() and
|
||||
LocalFlow::useToNextUse(use1, use2)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
query predicate use_use_edge(NameNode use1, NameNode use2) {
|
||||
exists(SsaSourceVariable x | x.getName() = "x" |
|
||||
use1 = x.getAUse() and
|
||||
use2 = x.getAUse() and
|
||||
LocalFlow::useToNextUse(use1, use2)
|
||||
)
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
uniqueNodeToString
|
||||
parameterCallable
|
||||
localFlowIsLocal
|
||||
readStepIsLocal
|
||||
storeStepIsLocal
|
||||
compatibleTypesReflexive
|
||||
unreachableNodeCCtx
|
||||
localCallNodes
|
||||
postIsNotPre
|
||||
postHasUniquePre
|
||||
uniquePostUpdate
|
||||
postIsInSameCallable
|
||||
reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
uniqueContentApprox
|
||||
identityLocalStep
|
||||
missingArgumentCall
|
||||
multipleArgumentCall
|
||||
@@ -1,2 +0,0 @@
|
||||
import python
|
||||
import experimental.dataflow.TestUtil.DataFlowConsistency
|
||||
Reference in New Issue
Block a user