Compare commits

...

91 Commits

Author SHA1 Message Date
Alexandre Boulgakov
3c695e3555 Swift: Remove workaround for LWG/issue3657. 2023-06-13 22:56:15 +01:00
yoff
1d65284011 Merge pull request #13209 from yoff/python/container-summaries-2
python: Container summaries, part 2
2023-06-13 18:17:09 +02:00
Rasmus Lerchedahl Petersen
775f3eaf56 python: make copy a dataflow step 2023-06-13 17:07:41 +02:00
Alexandre Boulgakov
7280f07611 Merge pull request #13336 from github/sashabu/c++20-todos
Swift: Fix some C++20 todos.
2023-06-13 15:25:29 +01:00
Alexandre Boulgakov
f5d6f50851 Merge pull request #13335 from github/sashabu/c++20
Build: Bump build mode to C++20.
2023-06-13 15:03:01 +01:00
yoff
4056358863 Merge pull request #13438 from RasmusWL/flask-render-string
Python: Add modeling of `flask.render_template_string`
2023-06-13 14:56:43 +02:00
Rasmus Wriedt Larsen
2b7fc94aef Python: Fix validTest.py expectation 2023-06-13 12:11:28 +02:00
Erik Krogh Kristensen
4dc596f0fb Merge pull request #13381 from erik-krogh/mongooseFindByIdAndUpdate
JS: remove the second argument of findByIdAndUpdate as a NoSQL sink
2023-06-13 11:59:58 +02:00
Rasmus Lerchedahl Petersen
b709ed47e1 python: add test 2023-06-13 11:20:15 +02:00
Jeroen Ketema
6413fcc0f9 Merge pull request #13439 from jketema/go-dead
Go: Remove commented out code from test
2023-06-13 10:33:51 +02:00
Jeroen Ketema
d035491c6f Go: Remove commented out code from test 2023-06-13 10:13:42 +02:00
Jeroen Ketema
c3ba206b6a Merge pull request #13346 from jketema/inline-2
Update inline expectation tests to use parameterized module
2023-06-13 10:10:55 +02:00
yoff
2a5173c331 Update python/ql/lib/semmle/python/frameworks/Stdlib.qll
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2023-06-13 10:04:46 +02:00
Asger F
0d45074caa Merge pull request #13422 from asgerf/rb/map_filter
Ruby: fix bug in filter_map summary
2023-06-13 09:43:47 +02:00
Tamás Vajk
aed6a75cd4 Merge pull request #13420 from tamasvajk/feature/standalone-mscorlib
C#: Make sure System.Private.CoreLib is added only once as a reference in standalone extraction
2023-06-13 09:29:16 +02:00
Rasmus Wriedt Larsen
6526364045 Python: Add modeling of flask.render_template_string 2023-06-12 21:18:31 +02:00
erik-krogh
3fd9f26b52 use consistent indentation in mongoose.js 2023-06-12 16:40:42 +02:00
erik-krogh
cd6f738f72 add mongoose.Types.ObjectId.isValid as a sanitizer-guard for NoSQL injection 2023-06-12 16:38:11 +02:00
Erik Krogh Kristensen
798f3880c9 Merge pull request #13402 from erik-krogh/deps-some-py
Py: delete some old deprecations
2023-06-12 11:29:44 +02:00
Calum Grant
0163fb8d9f Merge pull request #13391 from github/RasmusWL/experimental-query-id
Python: Avoid duplicated query-id
2023-06-12 10:10:51 +01:00
Tamas Vajk
cdf1c2639d C#: Only include CoreLib.dll when UseMscorlib option is set 2023-06-12 11:03:26 +02:00
Arthur Baars
fad73d71e5 Merge pull request #13307 from hmac/amammad-ruby-YAMLunsafeLoad
Ruby: Add YAML unsafe deserialization sinks
2023-06-12 10:43:37 +02:00
Asger F
452af312ff Ruby: change note 2023-06-12 10:07:26 +02:00
Tony Torralba
6b9c00e9cc Merge pull request #13429 from github/workflow/coverage/update
Update CSV framework coverage reports
2023-06-12 08:47:40 +02:00
github-actions[bot]
a628384d83 Add changed framework coverage reports 2023-06-12 00:18:38 +00:00
erik-krogh
42d67d0137 add change-note 2023-06-09 15:24:12 +02:00
erik-krogh
6dfeb2536b delete old deprecations 2023-06-09 15:12:23 +02:00
Asger F
d47477bd3b Ruby: update line numbers in expectation file 2023-06-09 14:52:21 +02:00
Asger F
a50d91ea48 Ruby: fix bug in filter_map summary 2023-06-09 14:31:10 +02:00
Jami
f222cce2e5 Merge pull request #13418 from jcogs33/jcogs33/fix-typo-in-parameterized-module-docs
Docs: fix typo in spelling of keyword
2023-06-09 08:17:07 -04:00
Anders Schack-Mulligen
1b7bbf6320 Merge pull request #13083 from aschackmull/dataflow/typestrengthen
Dataflow: Strengthen tracked types.
2023-06-09 13:23:30 +02:00
Mathias Vorreiter Pedersen
74ed9f535c Merge pull request #13406 from MathiasVP/fix-++-problem
C++: Fix the `++` problem
2023-06-09 11:20:00 +01:00
Tamas Vajk
bf3677df16 C#: Make sure System.Private.CoreLib is added only once as a reference in standalone extraction 2023-06-09 11:29:44 +02:00
Jeroen Ketema
4485560f43 Ruby: Rewrite inline expectation tests to use parameterized module 2023-06-09 10:43:05 +02:00
Jeroen Ketema
9633f00ed1 QL-for-QL: Rewrite inline expectation tests to use parameterized module 2023-06-09 10:42:46 +02:00
Jeroen Ketema
8f599faf85 Python: Rewrite inline expectation tests to use parameterized module 2023-06-09 10:42:29 +02:00
Jeroen Ketema
49993b023e Java: Rewrite inline expectation tests to use parameterized module 2023-06-09 10:42:17 +02:00
Jeroen Ketema
97c4f497bc Go: Rewrite inline expectation tests to use parameterized module 2023-06-09 10:41:21 +02:00
Tony Torralba
0cef5651e2 Merge pull request #13417 from github/workflow/coverage/update
Update CSV framework coverage reports
2023-06-09 09:27:03 +02:00
Asger F
bdbbde347e Merge pull request #13407 from asgerf/rb/restrict-orm-tracking
Ruby: restrict ORM tracking to calls
2023-06-09 09:13:01 +02:00
Anders Schack-Mulligen
44b09507ab Merge pull request #13408 from aschackmull/java/loginjection-perf
Java: Add more negation context to reduce string ops and improve perf.
2023-06-09 08:44:27 +02:00
Anders Schack-Mulligen
68f1e40370 Java/C#: Add change notes. 2023-06-09 08:37:36 +02:00
Anders Schack-Mulligen
85d6b44d92 Java: Fix test output. 2023-06-09 08:37:36 +02:00
Anders Schack-Mulligen
d230509905 Dataflow: Address review comments. 2023-06-09 08:37:36 +02:00
Anders Schack-Mulligen
95afd551ff Java: Fix qltest 2023-06-09 08:37:36 +02:00
Anders Schack-Mulligen
4399138c82 Dataflow: Fix QL4QL alert. 2023-06-09 08:37:36 +02:00
Anders Schack-Mulligen
53f2b8aab0 Dataflow: Sync. 2023-06-09 08:37:36 +02:00
Anders Schack-Mulligen
8a584b78ac Dataflow: Enable type strengthening in partial flow. 2023-06-09 08:37:36 +02:00
Anders Schack-Mulligen
441ccef6c4 Dataflow: Bugfix, use arg type rather than strengthened param type. 2023-06-09 08:37:36 +02:00
Anders Schack-Mulligen
a0a9d30286 Java: Fix qltests. 2023-06-09 08:37:35 +02:00
Anders Schack-Mulligen
21dea62e99 C#: Fix qltests. 2023-06-09 08:37:35 +02:00
Anders Schack-Mulligen
4633abe19e Java: Autoformat 2023-06-09 08:37:35 +02:00
Anders Schack-Mulligen
fd832416d8 Dataflow: Add empty type strengthening predicate for languages without type pruning. 2023-06-09 08:37:35 +02:00
Anders Schack-Mulligen
96c1b5b0a9 C#: Enable type strengthening. 2023-06-09 08:37:35 +02:00
Anders Schack-Mulligen
e8cea79f1d Dataflow: Sync. 2023-06-09 08:37:35 +02:00
Anders Schack-Mulligen
ad461a87b4 Dataflow: Strengthen tracked types. 2023-06-09 08:37:35 +02:00
Anders Schack-Mulligen
1d87f0793b Dataflow: Minor refactor. 2023-06-09 08:37:35 +02:00
Jami
7aede5034d Docs: fix typo 2023-06-08 22:52:34 -04:00
github-actions[bot]
81b08b4399 Add changed framework coverage reports 2023-06-09 00:18:12 +00:00
Alexandre Boulgakov
9ec09000e5 Swift: Remove no longer needed code. 2023-06-08 14:52:58 +01:00
Alexandre Boulgakov
5450585c1c Swift: Remove SwiftDiagnostic constructor (C++20 todo). 2023-06-08 13:11:14 +01:00
Alexandre Boulgakov
838130ca3a Swift: Fix some C++20 todos. 2023-06-08 13:11:14 +01:00
Alexandre Boulgakov
5952a729df Build: Bump build mode to C++20. 2023-06-08 13:10:43 +01:00
Anders Schack-Mulligen
5a2ac1b5ca Java: Add more negation context to reduce string ops and improve perf. 2023-06-08 14:04:57 +02:00
Asger F
d6741f655d Ruby: restrict ORM tracking to calls 2023-06-08 14:01:51 +02:00
Mathias Vorreiter Pedersen
a357eeedac C++: Accept test changes. 2023-06-08 12:50:16 +01:00
Mathias Vorreiter Pedersen
afb1129f27 C++: Ensure that postfix crement operations are handled properly in dataflow SSA. 2023-06-08 12:50:05 +01:00
Mathias Vorreiter Pedersen
57ae1e9ff7 C++: Add a testcase that started to fail in #13326. 2023-06-08 12:49:08 +01:00
Rasmus Wriedt Larsen
0c8b4251cf Python: Avoid duplicated query-id 2023-06-07 10:07:01 +02:00
Arthur Baars
7324d1705e Merge branch 'main' into amammad-ruby-YAMLunsafeLoad 2023-06-06 12:09:06 +02:00
Rasmus Lerchedahl Petersen
6755bb32fb Python: do not add read steps for collections 2023-06-01 15:18:05 +02:00
Harry Maclean
e70e3e52dc Ruby: fix typo in qhelp 2023-05-29 04:05:42 +00:00
Harry Maclean
ca1024e285 Ruby: Reword unsafe deserialization qhelp 2023-05-29 03:46:30 +00:00
Harry Maclean
e515981c81 Ruby: Remove unused examples 2023-05-27 12:01:00 +00:00
Harry Maclean
562065f29e Ruby: Add change note 2023-05-27 01:20:09 +00:00
Harry Maclean
b8c3cba4ff Ruby: Consolidate unsafe deserialization queries
Merge the experimental YAMLUnsafeDeserialization and
PlistUnsafeDeserialization queries into the generate
UnsafeDeserialization query in the default suite.

These queries look for some specific sinks that we now find in the
general query.

Also apply some small code and comment refactors.
2023-05-27 01:20:04 +00:00
amammad
d727d573d5 v4.2 write exact version of yaml.load default loader change 2023-05-27 01:15:29 +00:00
amammad
40e24b6b94 v4.1 fix file names in qhelp 2023-05-27 01:15:29 +00:00
amammad
335441ce04 v4: make variable names camelCase, some inhancement, remove some duplicates 2023-05-27 01:15:29 +00:00
amammad
e76ed9454a v3 add global taint steps for to_ruby of YAML/Psych 2023-05-27 01:15:24 +00:00
amammad
ad7e107ff5 add the new YAML/PLIST sinks into the existing rb/unsafe-deserialization query 2023-05-27 01:14:36 +00:00
amammad
b9296d3df8 v2.1 fix file names 2023-05-27 01:14:36 +00:00
amammad
4360a56b45 v2 add plist.parse_xml as a dangerous sink and enhancements on documents 2023-05-27 01:14:36 +00:00
amammad
0521ffe175 v1.4 correct dirs uppercase issue 2023-05-27 01:14:36 +00:00
amammad
0e343e5a12 v1.3 2023-05-27 01:14:36 +00:00
amammad
d96153a05e v1.2 change to PascalCase 2023-05-27 01:14:36 +00:00
amammad
e4b8a0e06d v1.1 2023-05-27 01:14:36 +00:00
amammad
486a5ac96f v1 2023-05-27 01:14:36 +00:00
Rasmus Lerchedahl Petersen
9cb83fcdc9 python: add summaries for
copy, pop, get, getitem, setdefault

Also add read steps to taint tracking.

Reading from a tainted collection can be done in two situations:
1. There is an acces path
    In this case a read step (possibly from a flow summary)
    gives rise to a taint step.
2. There is no access path
    In this case an explicit taint step (possibly via a flow
    summary) should exist.
2023-05-26 14:04:15 +02:00
Rasmus Lerchedahl Petersen
144df9a39e python: remove explicit dataflow steps 2023-05-26 13:24:22 +02:00
Rasmus Lerchedahl Petersen
8d4f9447b1 python: remove explicit steps
copy, pop, get, popitem
2023-05-26 13:22:54 +02:00
513 changed files with 9370 additions and 11120 deletions

View File

@@ -1,3 +1,3 @@
build --repo_env=CC=clang --repo_env=CXX=clang++ --cxxopt="-std=c++17" build --repo_env=CC=clang --repo_env=CXX=clang++ --cxxopt="-std=c++20"
try-import %workspace%/local.bazelrc try-import %workspace%/local.bazelrc

View File

@@ -1135,8 +1135,8 @@ module Impl<FullStateConfigSig Config> {
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow
); );
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap); predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t);
bindingset[typ, contentType] bindingset[typ, contentType]
predicate typecheckStore(Typ typ, DataFlowType contentType); predicate typecheckStore(Typ typ, DataFlowType contentType);
@@ -1199,17 +1199,21 @@ module Impl<FullStateConfigSig Config> {
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
ApOption argAp, Typ t, Ap ap, ApApprox apa ApOption argAp, Typ t, Ap ap, ApApprox apa
) { ) {
fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t, ap, apa) and fwdFlow1(node, state, cc, summaryCtx, argT, argAp, _, t, ap, apa)
PrevStage::revFlow(node, state, apa) and
filter(node, state, t, ap)
} }
pragma[inline] private predicate fwdFlow1(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
ApOption argAp, Typ t, Ap ap ApOption argAp, Typ t0, Typ t, Ap ap, ApApprox apa
) { ) {
fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t0, ap, apa) and
PrevStage::revFlow(node, state, apa) and
filter(node, state, t0, ap, t)
}
pragma[nomagic]
private predicate typeStrengthen(Typ t0, Ap ap, Typ t) {
fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t
} }
pragma[assume_small_delta] pragma[assume_small_delta]
@@ -1339,6 +1343,11 @@ module Impl<FullStateConfigSig Config> {
private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) { private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) {
fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and
cons = apCons(c, t1, tail) cons = apCons(c, t1, tail)
or
exists(Typ t0 |
typeStrengthen(t0, cons, t2) and
fwdFlowConsCand(t0, cons, c, t1, tail)
)
} }
pragma[nomagic] pragma[nomagic]
@@ -1359,7 +1368,7 @@ module Impl<FullStateConfigSig Config> {
ParamNodeOption summaryCtx, TypOption argT, ApOption argAp ParamNodeOption summaryCtx, TypOption argT, ApOption argAp
) { ) {
exists(ApHeadContent apc | exists(ApHeadContent apc |
fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap) and fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap, _) and
apc = getHeadContent(ap) and apc = getHeadContent(ap) and
readStepCand0(node1, apc, c, node2) readStepCand0(node1, apc, c, node2)
) )
@@ -1520,14 +1529,14 @@ module Impl<FullStateConfigSig Config> {
NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap
) { ) {
revFlow0(node, state, returnCtx, returnAp, ap) and revFlow0(node, state, returnCtx, returnAp, ap) and
fwdFlow(node, state, _, _, _, _, _, ap) fwdFlow(node, state, _, _, _, _, _, ap, _)
} }
pragma[nomagic] pragma[nomagic]
private predicate revFlow0( private predicate revFlow0(
NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap
) { ) {
fwdFlow(node, state, _, _, _, _, _, ap) and fwdFlow(node, state, _, _, _, _, _, ap, _) and
sinkNode(node, state) and sinkNode(node, state) and
( (
if hasSinkCallCtx() if hasSinkCallCtx()
@@ -1780,13 +1789,13 @@ module Impl<FullStateConfigSig Config> {
boolean fwd, int nodes, int fields, int conscand, int states, int tuples boolean fwd, int nodes, int fields, int conscand, int states, int tuples
) { ) {
fwd = true and fwd = true and
nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _)) and nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _, _)) and
fields = count(Content f0 | fwdConsCand(f0, _, _)) and fields = count(Content f0 | fwdConsCand(f0, _, _)) and
conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and
states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _, _)) and
tuples = tuples =
count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap)) ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap, _))
or or
fwd = false and fwd = false and
nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and
@@ -1963,10 +1972,10 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
PrevStage::revFlowState(state) and PrevStage::revFlowState(state) and
exists(t) and t0 = t and
exists(ap) and exists(ap) and
not stateBarrier(node, state) and not stateBarrier(node, state) and
( (
@@ -2197,8 +2206,8 @@ module Impl<FullStateConfigSig Config> {
import BooleanCallContext import BooleanCallContext
predicate localStep( predicate localStep(
NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t,
DataFlowType t, LocalCc lcc LocalCc lcc
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and
exists(lcc) exists(lcc)
@@ -2218,10 +2227,16 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
exists(state) and exists(state) and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and // We can get away with not using type strengthening here, since we aren't
// going to use the tracked types in the construction of Stage 4 access
// paths. For Stage 4 and onwards, the tracked types must be consistent as
// the cons candidates including types are used to construct subsequent
// access path approximations.
t0 = t and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t0) else any()) and
( (
notExpectsContent(node) notExpectsContent(node)
or or
@@ -2241,6 +2256,16 @@ module Impl<FullStateConfigSig Config> {
import MkStage<Stage2>::Stage<Stage3Param> import MkStage<Stage2>::Stage<Stage3Param>
} }
bindingset[node, t0]
private predicate strengthenType(NodeEx node, DataFlowType t0, DataFlowType t) {
if castingNodeEx(node)
then
exists(DataFlowType nt | nt = node.getDataFlowType() |
if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0)
)
else t = t0
}
private module Stage4Param implements MkStage<Stage3>::StageParam { private module Stage4Param implements MkStage<Stage3>::StageParam {
private module PrevStage = Stage3; private module PrevStage = Stage3;
@@ -2274,8 +2299,8 @@ module Impl<FullStateConfigSig Config> {
pragma[nomagic] pragma[nomagic]
predicate localStep( predicate localStep(
NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t,
DataFlowType t, LocalCc lcc LocalCc lcc
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and
PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and
@@ -2333,11 +2358,11 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
exists(state) and exists(state) and
not clear(node, ap) and not clear(node, ap) and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and strengthenType(node, t0, t) and
( (
notExpectsContent(node) notExpectsContent(node)
or or
@@ -2365,7 +2390,7 @@ module Impl<FullStateConfigSig Config> {
exists(AccessPathFront apf | exists(AccessPathFront apf |
Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and
Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _, Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _,
apf) apf, _)
) )
} }
@@ -2579,8 +2604,8 @@ module Impl<FullStateConfigSig Config> {
import LocalCallContext import LocalCallContext
predicate localStep( predicate localStep(
NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t,
DataFlowType t, LocalCc lcc LocalCc lcc
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and
PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and
@@ -2609,9 +2634,9 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and strengthenType(node, t0, t) and
exists(state) and exists(state) and
exists(ap) exists(ap)
} }
@@ -2632,7 +2657,7 @@ module Impl<FullStateConfigSig Config> {
Stage5::parameterMayFlowThrough(p, _) and Stage5::parameterMayFlowThrough(p, _) and
Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and
Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _, Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _,
TAccessPathApproxSome(apa), _, apa0) TAccessPathApproxSome(apa), _, apa0, _)
) )
} }
@@ -2649,7 +2674,7 @@ module Impl<FullStateConfigSig Config> {
TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) {
exists(AccessPathApprox apa | ap.getApprox() = apa | exists(AccessPathApprox apa | ap.getApprox() = apa |
Stage5::parameterMayFlowThrough(p, apa) and Stage5::parameterMayFlowThrough(p, apa) and
Stage5::fwdFlow(p, state, _, _, _, _, t, apa) and Stage5::fwdFlow(p, state, _, _, Option<DataFlowType>::some(t), _, _, apa, _) and
Stage5::revFlow(p, state, _) Stage5::revFlow(p, state, _)
) )
} }
@@ -2820,9 +2845,7 @@ module Impl<FullStateConfigSig Config> {
ap = TAccessPathNil() ap = TAccessPathNil()
or or
// ... or a step from an existing PathNode to another node. // ... or a step from an existing PathNode to another node.
pathStep(_, node, state, cc, sc, t, ap) and pathStep(_, node, state, cc, sc, t, ap)
Stage5::revFlow(node, state, ap.getApprox()) and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any())
} or } or
TPathNodeSink(NodeEx node, FlowState state) { TPathNodeSink(NodeEx node, FlowState state) {
exists(PathNodeMid sink | exists(PathNodeMid sink |
@@ -3340,13 +3363,24 @@ module Impl<FullStateConfigSig Config> {
ap = mid.getAp() ap = mid.getAp()
} }
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t,
AccessPath ap
) {
exists(DataFlowType t0 |
pathStep0(mid, node, state, cc, sc, t0, ap) and
Stage5::revFlow(node, state, ap.getApprox()) and
strengthenType(node, t0, t)
)
}
/** /**
* Holds if data may flow from `mid` to `node`. The last step in or out of * Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`. * a callable is recorded by `cc`.
*/ */
pragma[assume_small_delta] pragma[assume_small_delta]
pragma[nomagic] pragma[nomagic]
private predicate pathStep( private predicate pathStep0(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t,
AccessPath ap AccessPath ap
) { ) {
@@ -3964,7 +3998,7 @@ module Impl<FullStateConfigSig Config> {
ap = TPartialNil() and ap = TPartialNil() and
exists(explorationLimit()) exists(explorationLimit())
or or
partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, sc4, t, ap) and partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and
distSrc(node.getEnclosingCallable()) <= explorationLimit() distSrc(node.getEnclosingCallable()) <= explorationLimit()
} or } or
TPartialPathNodeRev( TPartialPathNodeRev(
@@ -3990,11 +4024,20 @@ module Impl<FullStateConfigSig Config> {
} }
pragma[nomagic] pragma[nomagic]
private predicate partialPathNodeMk0( private predicate partialPathStep(
NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1,
TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap
) { ) {
partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and partialPathStep1(mid, node, state, cc, sc1, sc2, sc3, sc4, _, t, ap)
}
pragma[nomagic]
private predicate partialPathStep1(
PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1,
TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t0, DataFlowType t,
PartialAccessPath ap
) {
partialPathStep0(mid, node, state, cc, sc1, sc2, sc3, sc4, t0, ap) and
not fullBarrier(node) and not fullBarrier(node) and
not stateBarrier(node, state) and not stateBarrier(node, state) and
not clearsContentEx(node, ap.getHead()) and not clearsContentEx(node, ap.getHead()) and
@@ -4002,9 +4045,14 @@ module Impl<FullStateConfigSig Config> {
notExpectsContent(node) or notExpectsContent(node) or
expectsContentEx(node, ap.getHead()) expectsContentEx(node, ap.getHead())
) and ) and
if node.asNode() instanceof CastingNode strengthenType(node, t0, t)
then compatibleTypes(node.getDataFlowType(), t) }
else any()
pragma[nomagic]
private predicate partialPathTypeStrengthen(
DataFlowType t0, PartialAccessPath ap, DataFlowType t
) {
partialPathStep1(_, _, _, _, _, _, _, _, t0, t, ap) and t0 != t
} }
/** /**
@@ -4183,7 +4231,8 @@ module Impl<FullStateConfigSig Config> {
} }
} }
private predicate partialPathStep( pragma[nomagic]
private predicate partialPathStep0(
PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1,
TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap
) { ) {
@@ -4309,6 +4358,11 @@ module Impl<FullStateConfigSig Config> {
DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2 DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2
) { ) {
partialPathStoreStep(_, t1, ap1, c, _, t2, ap2) partialPathStoreStep(_, t1, ap1, c, _, t2, ap2)
or
exists(DataFlowType t0 |
partialPathTypeStrengthen(t0, ap2, t2) and
apConsFwd(t1, ap1, c, t0, ap2)
)
} }
pragma[nomagic] pragma[nomagic]

View File

@@ -205,6 +205,8 @@ predicate clearsContent(Node n, Content c) {
*/ */
predicate expectsContent(Node n, ContentSet c) { none() } predicate expectsContent(Node n, ContentSet c) { none() }
predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() }
/** Gets the type of `n` used for type pruning. */ /** Gets the type of `n` used for type pruning. */
Type getNodeType(Node n) { Type getNodeType(Node n) {
suppressUnusedNode(n) and suppressUnusedNode(n) and

View File

@@ -1135,8 +1135,8 @@ module Impl<FullStateConfigSig Config> {
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow
); );
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap); predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t);
bindingset[typ, contentType] bindingset[typ, contentType]
predicate typecheckStore(Typ typ, DataFlowType contentType); predicate typecheckStore(Typ typ, DataFlowType contentType);
@@ -1199,17 +1199,21 @@ module Impl<FullStateConfigSig Config> {
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
ApOption argAp, Typ t, Ap ap, ApApprox apa ApOption argAp, Typ t, Ap ap, ApApprox apa
) { ) {
fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t, ap, apa) and fwdFlow1(node, state, cc, summaryCtx, argT, argAp, _, t, ap, apa)
PrevStage::revFlow(node, state, apa) and
filter(node, state, t, ap)
} }
pragma[inline] private predicate fwdFlow1(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
ApOption argAp, Typ t, Ap ap ApOption argAp, Typ t0, Typ t, Ap ap, ApApprox apa
) { ) {
fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t0, ap, apa) and
PrevStage::revFlow(node, state, apa) and
filter(node, state, t0, ap, t)
}
pragma[nomagic]
private predicate typeStrengthen(Typ t0, Ap ap, Typ t) {
fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t
} }
pragma[assume_small_delta] pragma[assume_small_delta]
@@ -1339,6 +1343,11 @@ module Impl<FullStateConfigSig Config> {
private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) { private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) {
fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and
cons = apCons(c, t1, tail) cons = apCons(c, t1, tail)
or
exists(Typ t0 |
typeStrengthen(t0, cons, t2) and
fwdFlowConsCand(t0, cons, c, t1, tail)
)
} }
pragma[nomagic] pragma[nomagic]
@@ -1359,7 +1368,7 @@ module Impl<FullStateConfigSig Config> {
ParamNodeOption summaryCtx, TypOption argT, ApOption argAp ParamNodeOption summaryCtx, TypOption argT, ApOption argAp
) { ) {
exists(ApHeadContent apc | exists(ApHeadContent apc |
fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap) and fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap, _) and
apc = getHeadContent(ap) and apc = getHeadContent(ap) and
readStepCand0(node1, apc, c, node2) readStepCand0(node1, apc, c, node2)
) )
@@ -1520,14 +1529,14 @@ module Impl<FullStateConfigSig Config> {
NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap
) { ) {
revFlow0(node, state, returnCtx, returnAp, ap) and revFlow0(node, state, returnCtx, returnAp, ap) and
fwdFlow(node, state, _, _, _, _, _, ap) fwdFlow(node, state, _, _, _, _, _, ap, _)
} }
pragma[nomagic] pragma[nomagic]
private predicate revFlow0( private predicate revFlow0(
NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap
) { ) {
fwdFlow(node, state, _, _, _, _, _, ap) and fwdFlow(node, state, _, _, _, _, _, ap, _) and
sinkNode(node, state) and sinkNode(node, state) and
( (
if hasSinkCallCtx() if hasSinkCallCtx()
@@ -1780,13 +1789,13 @@ module Impl<FullStateConfigSig Config> {
boolean fwd, int nodes, int fields, int conscand, int states, int tuples boolean fwd, int nodes, int fields, int conscand, int states, int tuples
) { ) {
fwd = true and fwd = true and
nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _)) and nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _, _)) and
fields = count(Content f0 | fwdConsCand(f0, _, _)) and fields = count(Content f0 | fwdConsCand(f0, _, _)) and
conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and
states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _, _)) and
tuples = tuples =
count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap)) ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap, _))
or or
fwd = false and fwd = false and
nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and
@@ -1963,10 +1972,10 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
PrevStage::revFlowState(state) and PrevStage::revFlowState(state) and
exists(t) and t0 = t and
exists(ap) and exists(ap) and
not stateBarrier(node, state) and not stateBarrier(node, state) and
( (
@@ -2197,8 +2206,8 @@ module Impl<FullStateConfigSig Config> {
import BooleanCallContext import BooleanCallContext
predicate localStep( predicate localStep(
NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t,
DataFlowType t, LocalCc lcc LocalCc lcc
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and
exists(lcc) exists(lcc)
@@ -2218,10 +2227,16 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
exists(state) and exists(state) and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and // We can get away with not using type strengthening here, since we aren't
// going to use the tracked types in the construction of Stage 4 access
// paths. For Stage 4 and onwards, the tracked types must be consistent as
// the cons candidates including types are used to construct subsequent
// access path approximations.
t0 = t and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t0) else any()) and
( (
notExpectsContent(node) notExpectsContent(node)
or or
@@ -2241,6 +2256,16 @@ module Impl<FullStateConfigSig Config> {
import MkStage<Stage2>::Stage<Stage3Param> import MkStage<Stage2>::Stage<Stage3Param>
} }
bindingset[node, t0]
private predicate strengthenType(NodeEx node, DataFlowType t0, DataFlowType t) {
if castingNodeEx(node)
then
exists(DataFlowType nt | nt = node.getDataFlowType() |
if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0)
)
else t = t0
}
private module Stage4Param implements MkStage<Stage3>::StageParam { private module Stage4Param implements MkStage<Stage3>::StageParam {
private module PrevStage = Stage3; private module PrevStage = Stage3;
@@ -2274,8 +2299,8 @@ module Impl<FullStateConfigSig Config> {
pragma[nomagic] pragma[nomagic]
predicate localStep( predicate localStep(
NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t,
DataFlowType t, LocalCc lcc LocalCc lcc
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and
PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and
@@ -2333,11 +2358,11 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
exists(state) and exists(state) and
not clear(node, ap) and not clear(node, ap) and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and strengthenType(node, t0, t) and
( (
notExpectsContent(node) notExpectsContent(node)
or or
@@ -2365,7 +2390,7 @@ module Impl<FullStateConfigSig Config> {
exists(AccessPathFront apf | exists(AccessPathFront apf |
Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and
Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _, Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _,
apf) apf, _)
) )
} }
@@ -2579,8 +2604,8 @@ module Impl<FullStateConfigSig Config> {
import LocalCallContext import LocalCallContext
predicate localStep( predicate localStep(
NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t,
DataFlowType t, LocalCc lcc LocalCc lcc
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and
PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and
@@ -2609,9 +2634,9 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and strengthenType(node, t0, t) and
exists(state) and exists(state) and
exists(ap) exists(ap)
} }
@@ -2632,7 +2657,7 @@ module Impl<FullStateConfigSig Config> {
Stage5::parameterMayFlowThrough(p, _) and Stage5::parameterMayFlowThrough(p, _) and
Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and
Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _, Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _,
TAccessPathApproxSome(apa), _, apa0) TAccessPathApproxSome(apa), _, apa0, _)
) )
} }
@@ -2649,7 +2674,7 @@ module Impl<FullStateConfigSig Config> {
TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) {
exists(AccessPathApprox apa | ap.getApprox() = apa | exists(AccessPathApprox apa | ap.getApprox() = apa |
Stage5::parameterMayFlowThrough(p, apa) and Stage5::parameterMayFlowThrough(p, apa) and
Stage5::fwdFlow(p, state, _, _, _, _, t, apa) and Stage5::fwdFlow(p, state, _, _, Option<DataFlowType>::some(t), _, _, apa, _) and
Stage5::revFlow(p, state, _) Stage5::revFlow(p, state, _)
) )
} }
@@ -2820,9 +2845,7 @@ module Impl<FullStateConfigSig Config> {
ap = TAccessPathNil() ap = TAccessPathNil()
or or
// ... or a step from an existing PathNode to another node. // ... or a step from an existing PathNode to another node.
pathStep(_, node, state, cc, sc, t, ap) and pathStep(_, node, state, cc, sc, t, ap)
Stage5::revFlow(node, state, ap.getApprox()) and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any())
} or } or
TPathNodeSink(NodeEx node, FlowState state) { TPathNodeSink(NodeEx node, FlowState state) {
exists(PathNodeMid sink | exists(PathNodeMid sink |
@@ -3340,13 +3363,24 @@ module Impl<FullStateConfigSig Config> {
ap = mid.getAp() ap = mid.getAp()
} }
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t,
AccessPath ap
) {
exists(DataFlowType t0 |
pathStep0(mid, node, state, cc, sc, t0, ap) and
Stage5::revFlow(node, state, ap.getApprox()) and
strengthenType(node, t0, t)
)
}
/** /**
* Holds if data may flow from `mid` to `node`. The last step in or out of * Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`. * a callable is recorded by `cc`.
*/ */
pragma[assume_small_delta] pragma[assume_small_delta]
pragma[nomagic] pragma[nomagic]
private predicate pathStep( private predicate pathStep0(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t,
AccessPath ap AccessPath ap
) { ) {
@@ -3964,7 +3998,7 @@ module Impl<FullStateConfigSig Config> {
ap = TPartialNil() and ap = TPartialNil() and
exists(explorationLimit()) exists(explorationLimit())
or or
partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, sc4, t, ap) and partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and
distSrc(node.getEnclosingCallable()) <= explorationLimit() distSrc(node.getEnclosingCallable()) <= explorationLimit()
} or } or
TPartialPathNodeRev( TPartialPathNodeRev(
@@ -3990,11 +4024,20 @@ module Impl<FullStateConfigSig Config> {
} }
pragma[nomagic] pragma[nomagic]
private predicate partialPathNodeMk0( private predicate partialPathStep(
NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1,
TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap
) { ) {
partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and partialPathStep1(mid, node, state, cc, sc1, sc2, sc3, sc4, _, t, ap)
}
pragma[nomagic]
private predicate partialPathStep1(
PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1,
TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t0, DataFlowType t,
PartialAccessPath ap
) {
partialPathStep0(mid, node, state, cc, sc1, sc2, sc3, sc4, t0, ap) and
not fullBarrier(node) and not fullBarrier(node) and
not stateBarrier(node, state) and not stateBarrier(node, state) and
not clearsContentEx(node, ap.getHead()) and not clearsContentEx(node, ap.getHead()) and
@@ -4002,9 +4045,14 @@ module Impl<FullStateConfigSig Config> {
notExpectsContent(node) or notExpectsContent(node) or
expectsContentEx(node, ap.getHead()) expectsContentEx(node, ap.getHead())
) and ) and
if node.asNode() instanceof CastingNode strengthenType(node, t0, t)
then compatibleTypes(node.getDataFlowType(), t) }
else any()
pragma[nomagic]
private predicate partialPathTypeStrengthen(
DataFlowType t0, PartialAccessPath ap, DataFlowType t
) {
partialPathStep1(_, _, _, _, _, _, _, _, t0, t, ap) and t0 != t
} }
/** /**
@@ -4183,7 +4231,8 @@ module Impl<FullStateConfigSig Config> {
} }
} }
private predicate partialPathStep( pragma[nomagic]
private predicate partialPathStep0(
PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1,
TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap
) { ) {
@@ -4309,6 +4358,11 @@ module Impl<FullStateConfigSig Config> {
DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2 DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2
) { ) {
partialPathStoreStep(_, t1, ap1, c, _, t2, ap2) partialPathStoreStep(_, t1, ap1, c, _, t2, ap2)
or
exists(DataFlowType t0 |
partialPathTypeStrengthen(t0, ap2, t2) and
apConsFwd(t1, ap1, c, t0, ap2)
)
} }
pragma[nomagic] pragma[nomagic]

View File

@@ -753,6 +753,8 @@ predicate clearsContent(Node n, Content c) {
*/ */
predicate expectsContent(Node n, ContentSet c) { none() } predicate expectsContent(Node n, ContentSet c) { none() }
predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() }
/** Gets the type of `n` used for type pruning. */ /** Gets the type of `n` used for type pruning. */
DataFlowType getNodeType(Node n) { DataFlowType getNodeType(Node n) {
suppressUnusedNode(n) and suppressUnusedNode(n) and

View File

@@ -364,7 +364,25 @@ abstract private class OperandBasedUse extends UseImpl {
OperandBasedUse() { any() } OperandBasedUse() { any() }
final override predicate hasIndexInBlock(IRBlock block, int index) { final override predicate hasIndexInBlock(IRBlock block, int index) {
operand.getUse() = block.getInstruction(index) // See the comment in `ssa0`'s `OperandBasedUse` for an explanation of this
// predicate's implementation.
exists(BaseSourceVariableInstruction base | base = this.getBase() |
if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand()
then
exists(Operand op, int indirectionIndex, int indirection |
indirectionIndex = this.getIndirectionIndex() and
indirection = this.getIndirection() and
op =
min(Operand cand, int i |
isUse(_, cand, base, indirection, indirectionIndex) and
block.getInstruction(i) = cand.getUse()
|
cand order by i
) and
block.getInstruction(index) = op.getUse()
)
else operand.getUse() = block.getInstruction(index)
)
} }
final Operand getOperand() { result = operand } final Operand getOperand() { result = operand }

View File

@@ -122,7 +122,46 @@ abstract private class OperandBasedUse extends UseImpl {
override string toString() { result = operand.toString() } override string toString() { result = operand.toString() }
final override predicate hasIndexInBlock(IRBlock block, int index) { final override predicate hasIndexInBlock(IRBlock block, int index) {
operand.getUse() = block.getInstruction(index) // Ideally, this would just be implemented as:
// ```
// operand.getUse() = block.getInstruction(index)
// ```
// but because the IR generated for a snippet such as
// ```
// int x = *p++;
// ```
// looks like
// ```
// r1(glval<int>) = VariableAddress[x] :
// r2(glval<int *>) = VariableAddress[p] :
// r3(int *) = Load[p] : &:r2, m1
// r4(int) = Constant[1] :
// r5(int *) = PointerAdd[4] : r3, r4
// m3(int *) = Store[p] : &:r2, r5
// r6(int *) = CopyValue : r3
// r7(int) = Load[?] : &:r6, ~m2
// m2(int) = Store[x] : &:r1, r7
// ```
// we need to ensure that the `r3` operand of the `CopyValue` instruction isn't seen as a fresh use
// of `p` that happens after the increment. So if the base instruction of this use comes from a
// post-fix crement operation we set the index of the SSA use that wraps the `r3` operand at the
// `CopyValue` instruction to be the same index as the `r3` operand at the `PointerAdd` instruction.
// This ensures that the SSA library doesn't create flow from the `PointerAdd` to `r6`.
exists(BaseSourceVariableInstruction base | base = this.getBase() |
if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand()
then
exists(Operand op |
op =
min(Operand cand, int i |
isUse(_, cand, base, _, _) and
block.getInstruction(i) = cand.getUse()
|
cand order by i
) and
block.getInstruction(index) = op.getUse()
)
else operand.getUse() = block.getInstruction(index)
)
} }
final override Cpp::Location getLocation() { result = operand.getLocation() } final override Cpp::Location getLocation() { result = operand.getLocation() }

View File

@@ -664,11 +664,6 @@ edges
| test.cpp:338:8:338:15 | * ... | test.cpp:342:8:342:17 | * ... | | test.cpp:338:8:338:15 | * ... | test.cpp:342:8:342:17 | * ... |
| test.cpp:341:8:341:17 | * ... | test.cpp:342:8:342:17 | * ... | | test.cpp:341:8:341:17 | * ... | test.cpp:342:8:342:17 | * ... |
| test.cpp:347:14:347:27 | new[] | test.cpp:348:15:348:16 | xs | | test.cpp:347:14:347:27 | new[] | test.cpp:348:15:348:16 | xs |
| test.cpp:348:15:348:16 | xs | test.cpp:350:16:350:19 | ... ++ |
| test.cpp:348:15:348:16 | xs | test.cpp:350:16:350:19 | ... ++ |
| test.cpp:350:16:350:19 | ... ++ | test.cpp:350:15:350:19 | Load: * ... |
| test.cpp:350:16:350:19 | ... ++ | test.cpp:350:16:350:19 | ... ++ |
| test.cpp:350:16:350:19 | ... ++ | test.cpp:350:16:350:19 | ... ++ |
| test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:16 | xs | | test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:16 | xs |
| test.cpp:356:15:356:16 | xs | test.cpp:356:15:356:23 | ... + ... | | test.cpp:356:15:356:16 | xs | test.cpp:356:15:356:23 | ... + ... |
| test.cpp:356:15:356:16 | xs | test.cpp:356:15:356:23 | ... + ... | | test.cpp:356:15:356:16 | xs | test.cpp:356:15:356:23 | ... + ... |
@@ -1057,10 +1052,6 @@ nodes
| test.cpp:342:8:342:17 | * ... | semmle.label | * ... | | test.cpp:342:8:342:17 | * ... | semmle.label | * ... |
| test.cpp:347:14:347:27 | new[] | semmle.label | new[] | | test.cpp:347:14:347:27 | new[] | semmle.label | new[] |
| test.cpp:348:15:348:16 | xs | semmle.label | xs | | test.cpp:348:15:348:16 | xs | semmle.label | xs |
| test.cpp:350:15:350:19 | Load: * ... | semmle.label | Load: * ... |
| test.cpp:350:16:350:19 | ... ++ | semmle.label | ... ++ |
| test.cpp:350:16:350:19 | ... ++ | semmle.label | ... ++ |
| test.cpp:350:16:350:19 | ... ++ | semmle.label | ... ++ |
| test.cpp:355:14:355:27 | new[] | semmle.label | new[] | | test.cpp:355:14:355:27 | new[] | semmle.label | new[] |
| test.cpp:356:15:356:16 | xs | semmle.label | xs | | test.cpp:356:15:356:16 | xs | semmle.label | xs |
| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... | | test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... |
@@ -1118,7 +1109,6 @@ subpaths
| test.cpp:264:13:264:14 | Load: * ... | test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:260:13:260:24 | new[] | new[] | test.cpp:261:19:261:21 | len | len | | test.cpp:264:13:264:14 | Load: * ... | test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:260:13:260:24 | new[] | new[] | test.cpp:261:19:261:21 | len | len |
| test.cpp:274:5:274:10 | Store: ... = ... | test.cpp:270:13:270:24 | new[] | test.cpp:274:5:274:10 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:270:13:270:24 | new[] | new[] | test.cpp:271:19:271:21 | len | len | | test.cpp:274:5:274:10 | Store: ... = ... | test.cpp:270:13:270:24 | new[] | test.cpp:274:5:274:10 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:270:13:270:24 | new[] | new[] | test.cpp:271:19:271:21 | len | len |
| test.cpp:308:5:308:29 | Store: ... = ... | test.cpp:304:15:304:26 | new[] | test.cpp:308:5:308:29 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:304:15:304:26 | new[] | new[] | test.cpp:308:8:308:10 | ... + ... | ... + ... | | test.cpp:308:5:308:29 | Store: ... = ... | test.cpp:304:15:304:26 | new[] | test.cpp:308:5:308:29 | Store: ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:304:15:304:26 | new[] | new[] | test.cpp:308:8:308:10 | ... + ... | ... + ... |
| test.cpp:350:15:350:19 | Load: * ... | test.cpp:347:14:347:27 | new[] | test.cpp:350:15:350:19 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:347:14:347:27 | new[] | new[] | test.cpp:348:20:348:23 | size | size |
| test.cpp:358:14:358:26 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | | test.cpp:358:14:358:26 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size |
| test.cpp:359:14:359:32 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 2. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size | | test.cpp:359:14:359:32 | Load: * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 2. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size |
| test.cpp:372:15:372:16 | Load: * ... | test.cpp:363:14:363:27 | new[] | test.cpp:372:15:372:16 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:363:14:363:27 | new[] | new[] | test.cpp:365:19:365:22 | size | size | | test.cpp:372:15:372:16 | Load: * ... | test.cpp:363:14:363:27 | new[] | test.cpp:372:15:372:16 | Load: * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:363:14:363:27 | new[] | new[] | test.cpp:365:19:365:22 | size | size |

View File

@@ -347,7 +347,7 @@ void test24(unsigned size) {
char *xs = new char[size]; char *xs = new char[size];
char *end = xs + size; char *end = xs + size;
if (xs < end) { if (xs < end) {
int val = *xs++; // GOOD [FALSE POSITIVE] int val = *xs++; // GOOD
} }
} }

View File

@@ -6584,6 +6584,13 @@
| taint.cpp:691:18:691:18 | s [post update] | taint.cpp:695:7:695:7 | s | | | taint.cpp:691:18:691:18 | s [post update] | taint.cpp:695:7:695:7 | s | |
| taint.cpp:691:20:691:20 | ref arg x | taint.cpp:694:9:694:9 | x | | | taint.cpp:691:20:691:20 | ref arg x | taint.cpp:694:9:694:9 | x | |
| taint.cpp:694:7:694:7 | s [post update] | taint.cpp:695:7:695:7 | s | | | taint.cpp:694:7:694:7 | s [post update] | taint.cpp:695:7:695:7 | s | |
| taint.cpp:700:13:700:18 | call to source | taint.cpp:702:11:702:11 | s | |
| taint.cpp:701:9:701:9 | p | taint.cpp:702:4:702:4 | p | |
| taint.cpp:702:4:702:4 | p | taint.cpp:702:4:702:6 | ... ++ | |
| taint.cpp:702:4:702:6 | ... ++ | taint.cpp:702:3:702:6 | * ... | TAINT |
| taint.cpp:702:4:702:6 | ... ++ | taint.cpp:703:8:703:8 | p | TAINT |
| taint.cpp:702:10:702:11 | * ... | taint.cpp:702:3:702:11 | ... = ... | |
| taint.cpp:702:11:702:11 | s | taint.cpp:702:10:702:11 | * ... | TAINT |
| vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | | | vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | |
| vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | | | vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | |
| vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | | | vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | |

View File

@@ -693,4 +693,13 @@ void test_argument_source_field_to_obj() {
sink(s); // $ SPURIOUS: ast,ir sink(s); // $ SPURIOUS: ast,ir
sink(s.x); // $ ast,ir sink(s.x); // $ ast,ir
sink(s.y); // clean sink(s.y); // clean
}
namespace strings {
void test_write_to_read_then_incr_then_deref() {
char* s = source();
char* p;
*p++ = *s;
sink(p); // $ ast ir
}
} }

View File

@@ -120,13 +120,13 @@ namespace Semmle.BuildAnalyser
UseReference(filename); UseReference(filename);
} }
ResolveConflicts();
if (options.UseMscorlib) if (options.UseMscorlib)
{ {
UseReference(typeof(object).Assembly.Location); UseReference(typeof(object).Assembly.Location);
} }
ResolveConflicts();
// Output the findings // Output the findings
foreach (var r in usedReferences.Keys) foreach (var r in usedReferences.Keys)
{ {

View File

@@ -0,0 +1,4 @@
---
category: majorAnalysis
---
* The data flow library now performs type strengthening. This increases precision for all data flow queries by excluding paths that can be inferred to be impossible due to incompatible types.

View File

@@ -1135,8 +1135,8 @@ module Impl<FullStateConfigSig Config> {
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow
); );
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap); predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t);
bindingset[typ, contentType] bindingset[typ, contentType]
predicate typecheckStore(Typ typ, DataFlowType contentType); predicate typecheckStore(Typ typ, DataFlowType contentType);
@@ -1199,17 +1199,21 @@ module Impl<FullStateConfigSig Config> {
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
ApOption argAp, Typ t, Ap ap, ApApprox apa ApOption argAp, Typ t, Ap ap, ApApprox apa
) { ) {
fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t, ap, apa) and fwdFlow1(node, state, cc, summaryCtx, argT, argAp, _, t, ap, apa)
PrevStage::revFlow(node, state, apa) and
filter(node, state, t, ap)
} }
pragma[inline] private predicate fwdFlow1(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
ApOption argAp, Typ t, Ap ap ApOption argAp, Typ t0, Typ t, Ap ap, ApApprox apa
) { ) {
fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t0, ap, apa) and
PrevStage::revFlow(node, state, apa) and
filter(node, state, t0, ap, t)
}
pragma[nomagic]
private predicate typeStrengthen(Typ t0, Ap ap, Typ t) {
fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t
} }
pragma[assume_small_delta] pragma[assume_small_delta]
@@ -1339,6 +1343,11 @@ module Impl<FullStateConfigSig Config> {
private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) { private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) {
fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and
cons = apCons(c, t1, tail) cons = apCons(c, t1, tail)
or
exists(Typ t0 |
typeStrengthen(t0, cons, t2) and
fwdFlowConsCand(t0, cons, c, t1, tail)
)
} }
pragma[nomagic] pragma[nomagic]
@@ -1359,7 +1368,7 @@ module Impl<FullStateConfigSig Config> {
ParamNodeOption summaryCtx, TypOption argT, ApOption argAp ParamNodeOption summaryCtx, TypOption argT, ApOption argAp
) { ) {
exists(ApHeadContent apc | exists(ApHeadContent apc |
fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap) and fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap, _) and
apc = getHeadContent(ap) and apc = getHeadContent(ap) and
readStepCand0(node1, apc, c, node2) readStepCand0(node1, apc, c, node2)
) )
@@ -1520,14 +1529,14 @@ module Impl<FullStateConfigSig Config> {
NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap
) { ) {
revFlow0(node, state, returnCtx, returnAp, ap) and revFlow0(node, state, returnCtx, returnAp, ap) and
fwdFlow(node, state, _, _, _, _, _, ap) fwdFlow(node, state, _, _, _, _, _, ap, _)
} }
pragma[nomagic] pragma[nomagic]
private predicate revFlow0( private predicate revFlow0(
NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap
) { ) {
fwdFlow(node, state, _, _, _, _, _, ap) and fwdFlow(node, state, _, _, _, _, _, ap, _) and
sinkNode(node, state) and sinkNode(node, state) and
( (
if hasSinkCallCtx() if hasSinkCallCtx()
@@ -1780,13 +1789,13 @@ module Impl<FullStateConfigSig Config> {
boolean fwd, int nodes, int fields, int conscand, int states, int tuples boolean fwd, int nodes, int fields, int conscand, int states, int tuples
) { ) {
fwd = true and fwd = true and
nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _)) and nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _, _)) and
fields = count(Content f0 | fwdConsCand(f0, _, _)) and fields = count(Content f0 | fwdConsCand(f0, _, _)) and
conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and
states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _, _)) and
tuples = tuples =
count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap)) ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap, _))
or or
fwd = false and fwd = false and
nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and
@@ -1963,10 +1972,10 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
PrevStage::revFlowState(state) and PrevStage::revFlowState(state) and
exists(t) and t0 = t and
exists(ap) and exists(ap) and
not stateBarrier(node, state) and not stateBarrier(node, state) and
( (
@@ -2197,8 +2206,8 @@ module Impl<FullStateConfigSig Config> {
import BooleanCallContext import BooleanCallContext
predicate localStep( predicate localStep(
NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t,
DataFlowType t, LocalCc lcc LocalCc lcc
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and
exists(lcc) exists(lcc)
@@ -2218,10 +2227,16 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
exists(state) and exists(state) and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and // We can get away with not using type strengthening here, since we aren't
// going to use the tracked types in the construction of Stage 4 access
// paths. For Stage 4 and onwards, the tracked types must be consistent as
// the cons candidates including types are used to construct subsequent
// access path approximations.
t0 = t and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t0) else any()) and
( (
notExpectsContent(node) notExpectsContent(node)
or or
@@ -2241,6 +2256,16 @@ module Impl<FullStateConfigSig Config> {
import MkStage<Stage2>::Stage<Stage3Param> import MkStage<Stage2>::Stage<Stage3Param>
} }
bindingset[node, t0]
private predicate strengthenType(NodeEx node, DataFlowType t0, DataFlowType t) {
if castingNodeEx(node)
then
exists(DataFlowType nt | nt = node.getDataFlowType() |
if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0)
)
else t = t0
}
private module Stage4Param implements MkStage<Stage3>::StageParam { private module Stage4Param implements MkStage<Stage3>::StageParam {
private module PrevStage = Stage3; private module PrevStage = Stage3;
@@ -2274,8 +2299,8 @@ module Impl<FullStateConfigSig Config> {
pragma[nomagic] pragma[nomagic]
predicate localStep( predicate localStep(
NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t,
DataFlowType t, LocalCc lcc LocalCc lcc
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and
PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and
@@ -2333,11 +2358,11 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
exists(state) and exists(state) and
not clear(node, ap) and not clear(node, ap) and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and strengthenType(node, t0, t) and
( (
notExpectsContent(node) notExpectsContent(node)
or or
@@ -2365,7 +2390,7 @@ module Impl<FullStateConfigSig Config> {
exists(AccessPathFront apf | exists(AccessPathFront apf |
Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and
Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _, Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _,
apf) apf, _)
) )
} }
@@ -2579,8 +2604,8 @@ module Impl<FullStateConfigSig Config> {
import LocalCallContext import LocalCallContext
predicate localStep( predicate localStep(
NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t,
DataFlowType t, LocalCc lcc LocalCc lcc
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and
PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and
@@ -2609,9 +2634,9 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and strengthenType(node, t0, t) and
exists(state) and exists(state) and
exists(ap) exists(ap)
} }
@@ -2632,7 +2657,7 @@ module Impl<FullStateConfigSig Config> {
Stage5::parameterMayFlowThrough(p, _) and Stage5::parameterMayFlowThrough(p, _) and
Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and
Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _, Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _,
TAccessPathApproxSome(apa), _, apa0) TAccessPathApproxSome(apa), _, apa0, _)
) )
} }
@@ -2649,7 +2674,7 @@ module Impl<FullStateConfigSig Config> {
TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) {
exists(AccessPathApprox apa | ap.getApprox() = apa | exists(AccessPathApprox apa | ap.getApprox() = apa |
Stage5::parameterMayFlowThrough(p, apa) and Stage5::parameterMayFlowThrough(p, apa) and
Stage5::fwdFlow(p, state, _, _, _, _, t, apa) and Stage5::fwdFlow(p, state, _, _, Option<DataFlowType>::some(t), _, _, apa, _) and
Stage5::revFlow(p, state, _) Stage5::revFlow(p, state, _)
) )
} }
@@ -2820,9 +2845,7 @@ module Impl<FullStateConfigSig Config> {
ap = TAccessPathNil() ap = TAccessPathNil()
or or
// ... or a step from an existing PathNode to another node. // ... or a step from an existing PathNode to another node.
pathStep(_, node, state, cc, sc, t, ap) and pathStep(_, node, state, cc, sc, t, ap)
Stage5::revFlow(node, state, ap.getApprox()) and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any())
} or } or
TPathNodeSink(NodeEx node, FlowState state) { TPathNodeSink(NodeEx node, FlowState state) {
exists(PathNodeMid sink | exists(PathNodeMid sink |
@@ -3340,13 +3363,24 @@ module Impl<FullStateConfigSig Config> {
ap = mid.getAp() ap = mid.getAp()
} }
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t,
AccessPath ap
) {
exists(DataFlowType t0 |
pathStep0(mid, node, state, cc, sc, t0, ap) and
Stage5::revFlow(node, state, ap.getApprox()) and
strengthenType(node, t0, t)
)
}
/** /**
* Holds if data may flow from `mid` to `node`. The last step in or out of * Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`. * a callable is recorded by `cc`.
*/ */
pragma[assume_small_delta] pragma[assume_small_delta]
pragma[nomagic] pragma[nomagic]
private predicate pathStep( private predicate pathStep0(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t,
AccessPath ap AccessPath ap
) { ) {
@@ -3964,7 +3998,7 @@ module Impl<FullStateConfigSig Config> {
ap = TPartialNil() and ap = TPartialNil() and
exists(explorationLimit()) exists(explorationLimit())
or or
partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, sc4, t, ap) and partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and
distSrc(node.getEnclosingCallable()) <= explorationLimit() distSrc(node.getEnclosingCallable()) <= explorationLimit()
} or } or
TPartialPathNodeRev( TPartialPathNodeRev(
@@ -3990,11 +4024,20 @@ module Impl<FullStateConfigSig Config> {
} }
pragma[nomagic] pragma[nomagic]
private predicate partialPathNodeMk0( private predicate partialPathStep(
NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1,
TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap
) { ) {
partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and partialPathStep1(mid, node, state, cc, sc1, sc2, sc3, sc4, _, t, ap)
}
pragma[nomagic]
private predicate partialPathStep1(
PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1,
TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t0, DataFlowType t,
PartialAccessPath ap
) {
partialPathStep0(mid, node, state, cc, sc1, sc2, sc3, sc4, t0, ap) and
not fullBarrier(node) and not fullBarrier(node) and
not stateBarrier(node, state) and not stateBarrier(node, state) and
not clearsContentEx(node, ap.getHead()) and not clearsContentEx(node, ap.getHead()) and
@@ -4002,9 +4045,14 @@ module Impl<FullStateConfigSig Config> {
notExpectsContent(node) or notExpectsContent(node) or
expectsContentEx(node, ap.getHead()) expectsContentEx(node, ap.getHead())
) and ) and
if node.asNode() instanceof CastingNode strengthenType(node, t0, t)
then compatibleTypes(node.getDataFlowType(), t) }
else any()
pragma[nomagic]
private predicate partialPathTypeStrengthen(
DataFlowType t0, PartialAccessPath ap, DataFlowType t
) {
partialPathStep1(_, _, _, _, _, _, _, _, t0, t, ap) and t0 != t
} }
/** /**
@@ -4183,7 +4231,8 @@ module Impl<FullStateConfigSig Config> {
} }
} }
private predicate partialPathStep( pragma[nomagic]
private predicate partialPathStep0(
PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1,
TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap
) { ) {
@@ -4309,6 +4358,11 @@ module Impl<FullStateConfigSig Config> {
DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2 DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2
) { ) {
partialPathStoreStep(_, t1, ap1, c, _, t2, ap2) partialPathStoreStep(_, t1, ap1, c, _, t2, ap2)
or
exists(DataFlowType t0 |
partialPathTypeStrengthen(t0, ap2, t2) and
apConsFwd(t1, ap1, c, t0, ap2)
)
} }
pragma[nomagic] pragma[nomagic]

View File

@@ -1984,6 +1984,21 @@ private class DataFlowUnknownType extends DataFlowType {
DataFlowUnknownType() { this = Gvn::getGlobalValueNumber(any(UnknownType ut)) } DataFlowUnknownType() { this = Gvn::getGlobalValueNumber(any(UnknownType ut)) }
} }
private predicate uselessTypebound(DataFlowType t) {
t instanceof DataFlowUnknownType or
t instanceof Gvn::TypeParameterGvnType
}
pragma[nomagic]
predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) {
t1 != t2 and
t1 = getANonTypeParameterSubTypeRestricted(t2)
or
t1 instanceof RelevantDataFlowType and
not uselessTypebound(t1) and
uselessTypebound(t2)
}
/** /**
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from * Holds if `t1` and `t2` are compatible, that is, whether data can flow from
* a node of type `t1` to a node of type `t2`. * a node of type `t1` to a node of type `t2`.

View File

@@ -214,8 +214,8 @@ edges
| CollectionFlow.cs:385:58:385:61 | dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:385:67:385:70 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | | CollectionFlow.cs:385:58:385:61 | dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:385:67:385:70 | access to parameter dict : Dictionary<T,T> [element, property Value] : A |
| CollectionFlow.cs:385:67:385:70 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:385:67:385:73 | access to indexer : A | | CollectionFlow.cs:385:67:385:70 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:385:67:385:73 | access to indexer : A |
| CollectionFlow.cs:387:59:387:62 | dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:387:68:387:71 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | | CollectionFlow.cs:387:59:387:62 | dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:387:68:387:71 | access to parameter dict : Dictionary<T,T> [element, property Value] : A |
| CollectionFlow.cs:387:68:387:71 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:387:68:387:79 | call to method First<KeyValuePair<Int32,T>> : Object [property Value] : A | | CollectionFlow.cs:387:68:387:71 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:387:68:387:79 | call to method First<KeyValuePair<Int32,T>> : KeyValuePair<Int32,T> [property Value] : A |
| CollectionFlow.cs:387:68:387:79 | call to method First<KeyValuePair<Int32,T>> : Object [property Value] : A | CollectionFlow.cs:387:68:387:85 | access to property Value : A | | CollectionFlow.cs:387:68:387:79 | call to method First<KeyValuePair<Int32,T>> : KeyValuePair<Int32,T> [property Value] : A | CollectionFlow.cs:387:68:387:85 | access to property Value : A |
| CollectionFlow.cs:389:60:389:63 | dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:389:69:389:72 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | | CollectionFlow.cs:389:60:389:63 | dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:389:69:389:72 | access to parameter dict : Dictionary<T,T> [element, property Value] : A |
| CollectionFlow.cs:389:69:389:72 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:389:69:389:79 | access to property Values : ICollection<T> [element] : A | | CollectionFlow.cs:389:69:389:72 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | CollectionFlow.cs:389:69:389:79 | access to property Values : ICollection<T> [element] : A |
| CollectionFlow.cs:389:69:389:79 | access to property Values : ICollection<T> [element] : A | CollectionFlow.cs:389:69:389:87 | call to method First<T> : A | | CollectionFlow.cs:389:69:389:79 | access to property Values : ICollection<T> [element] : A | CollectionFlow.cs:389:69:389:87 | call to method First<T> : A |
@@ -223,8 +223,8 @@ edges
| CollectionFlow.cs:391:67:391:70 | access to parameter dict : Dictionary<T,T> [element, property Key] : A | CollectionFlow.cs:391:67:391:75 | access to property Keys : ICollection<T> [element] : A | | CollectionFlow.cs:391:67:391:70 | access to parameter dict : Dictionary<T,T> [element, property Key] : A | CollectionFlow.cs:391:67:391:75 | access to property Keys : ICollection<T> [element] : A |
| CollectionFlow.cs:391:67:391:75 | access to property Keys : ICollection<T> [element] : A | CollectionFlow.cs:391:67:391:83 | call to method First<T> : A | | CollectionFlow.cs:391:67:391:75 | access to property Keys : ICollection<T> [element] : A | CollectionFlow.cs:391:67:391:83 | call to method First<T> : A |
| CollectionFlow.cs:393:57:393:60 | dict : Dictionary<T,T> [element, property Key] : A | CollectionFlow.cs:393:66:393:69 | access to parameter dict : Dictionary<T,T> [element, property Key] : A | | CollectionFlow.cs:393:57:393:60 | dict : Dictionary<T,T> [element, property Key] : A | CollectionFlow.cs:393:66:393:69 | access to parameter dict : Dictionary<T,T> [element, property Key] : A |
| CollectionFlow.cs:393:66:393:69 | access to parameter dict : Dictionary<T,T> [element, property Key] : A | CollectionFlow.cs:393:66:393:77 | call to method First<KeyValuePair<T,Int32>> : Object [property Key] : A | | CollectionFlow.cs:393:66:393:69 | access to parameter dict : Dictionary<T,T> [element, property Key] : A | CollectionFlow.cs:393:66:393:77 | call to method First<KeyValuePair<T,Int32>> : KeyValuePair<T,Int32> [property Key] : A |
| CollectionFlow.cs:393:66:393:77 | call to method First<KeyValuePair<T,Int32>> : Object [property Key] : A | CollectionFlow.cs:393:66:393:81 | access to property Key : A | | CollectionFlow.cs:393:66:393:77 | call to method First<KeyValuePair<T,Int32>> : KeyValuePair<T,Int32> [property Key] : A | CollectionFlow.cs:393:66:393:81 | access to property Key : A |
| CollectionFlow.cs:395:49:395:52 | args : A[] [element] : A | CollectionFlow.cs:395:63:395:66 | access to parameter args : A[] [element] : A | | CollectionFlow.cs:395:49:395:52 | args : A[] [element] : A | CollectionFlow.cs:395:63:395:66 | access to parameter args : A[] [element] : A |
| CollectionFlow.cs:395:49:395:52 | args : null [element] : A | CollectionFlow.cs:395:63:395:66 | access to parameter args : null [element] : A | | CollectionFlow.cs:395:49:395:52 | args : null [element] : A | CollectionFlow.cs:395:63:395:66 | access to parameter args : null [element] : A |
| CollectionFlow.cs:395:63:395:66 | access to parameter args : A[] [element] : A | CollectionFlow.cs:395:63:395:69 | access to array element | | CollectionFlow.cs:395:63:395:66 | access to parameter args : A[] [element] : A | CollectionFlow.cs:395:63:395:69 | access to array element |
@@ -440,7 +440,7 @@ nodes
| CollectionFlow.cs:385:67:385:73 | access to indexer : A | semmle.label | access to indexer : A | | CollectionFlow.cs:385:67:385:73 | access to indexer : A | semmle.label | access to indexer : A |
| CollectionFlow.cs:387:59:387:62 | dict : Dictionary<T,T> [element, property Value] : A | semmle.label | dict : Dictionary<T,T> [element, property Value] : A | | CollectionFlow.cs:387:59:387:62 | dict : Dictionary<T,T> [element, property Value] : A | semmle.label | dict : Dictionary<T,T> [element, property Value] : A |
| CollectionFlow.cs:387:68:387:71 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | semmle.label | access to parameter dict : Dictionary<T,T> [element, property Value] : A | | CollectionFlow.cs:387:68:387:71 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | semmle.label | access to parameter dict : Dictionary<T,T> [element, property Value] : A |
| CollectionFlow.cs:387:68:387:79 | call to method First<KeyValuePair<Int32,T>> : Object [property Value] : A | semmle.label | call to method First<KeyValuePair<Int32,T>> : Object [property Value] : A | | CollectionFlow.cs:387:68:387:79 | call to method First<KeyValuePair<Int32,T>> : KeyValuePair<Int32,T> [property Value] : A | semmle.label | call to method First<KeyValuePair<Int32,T>> : KeyValuePair<Int32,T> [property Value] : A |
| CollectionFlow.cs:387:68:387:85 | access to property Value : A | semmle.label | access to property Value : A | | CollectionFlow.cs:387:68:387:85 | access to property Value : A | semmle.label | access to property Value : A |
| CollectionFlow.cs:389:60:389:63 | dict : Dictionary<T,T> [element, property Value] : A | semmle.label | dict : Dictionary<T,T> [element, property Value] : A | | CollectionFlow.cs:389:60:389:63 | dict : Dictionary<T,T> [element, property Value] : A | semmle.label | dict : Dictionary<T,T> [element, property Value] : A |
| CollectionFlow.cs:389:69:389:72 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | semmle.label | access to parameter dict : Dictionary<T,T> [element, property Value] : A | | CollectionFlow.cs:389:69:389:72 | access to parameter dict : Dictionary<T,T> [element, property Value] : A | semmle.label | access to parameter dict : Dictionary<T,T> [element, property Value] : A |
@@ -452,7 +452,7 @@ nodes
| CollectionFlow.cs:391:67:391:83 | call to method First<T> : A | semmle.label | call to method First<T> : A | | CollectionFlow.cs:391:67:391:83 | call to method First<T> : A | semmle.label | call to method First<T> : A |
| CollectionFlow.cs:393:57:393:60 | dict : Dictionary<T,T> [element, property Key] : A | semmle.label | dict : Dictionary<T,T> [element, property Key] : A | | CollectionFlow.cs:393:57:393:60 | dict : Dictionary<T,T> [element, property Key] : A | semmle.label | dict : Dictionary<T,T> [element, property Key] : A |
| CollectionFlow.cs:393:66:393:69 | access to parameter dict : Dictionary<T,T> [element, property Key] : A | semmle.label | access to parameter dict : Dictionary<T,T> [element, property Key] : A | | CollectionFlow.cs:393:66:393:69 | access to parameter dict : Dictionary<T,T> [element, property Key] : A | semmle.label | access to parameter dict : Dictionary<T,T> [element, property Key] : A |
| CollectionFlow.cs:393:66:393:77 | call to method First<KeyValuePair<T,Int32>> : Object [property Key] : A | semmle.label | call to method First<KeyValuePair<T,Int32>> : Object [property Key] : A | | CollectionFlow.cs:393:66:393:77 | call to method First<KeyValuePair<T,Int32>> : KeyValuePair<T,Int32> [property Key] : A | semmle.label | call to method First<KeyValuePair<T,Int32>> : KeyValuePair<T,Int32> [property Key] : A |
| CollectionFlow.cs:393:66:393:81 | access to property Key : A | semmle.label | access to property Key : A | | CollectionFlow.cs:393:66:393:81 | access to property Key : A | semmle.label | access to property Key : A |
| CollectionFlow.cs:395:49:395:52 | args : A[] [element] : A | semmle.label | args : A[] [element] : A | | CollectionFlow.cs:395:49:395:52 | args : A[] [element] : A | semmle.label | args : A[] [element] : A |
| CollectionFlow.cs:395:49:395:52 | args : null [element] : A | semmle.label | args : null [element] : A | | CollectionFlow.cs:395:49:395:52 | args : null [element] : A | semmle.label | args : null [element] : A |

View File

@@ -149,9 +149,9 @@ namespace My.Qltest
static T Apply<S, T>(Func<S, T> f, S s) => throw null; static T Apply<S, T>(Func<S, T> f, S s) => throw null;
static S[] Map<S, T>(S[] elements, Func<S, T> f) => throw null; static T[] Map<S, T>(S[] elements, Func<S, T> f) => throw null;
static void Apply2<S>(Action<S> f, S s1, S s2) => throw null; static void Apply2(Action<object> f, D d1, D d2) => throw null;
static void Parse(string s, out int i) => throw null; static void Parse(string s, out int i) => throw null;
@@ -235,4 +235,4 @@ namespace My.Qltest
static void Sink(object o) { } static void Sink(object o) { }
} }
} }

View File

@@ -12,10 +12,10 @@ edges
| ExternalFlow.cs:30:13:30:16 | [post] this access : D [field Field] : Object | ExternalFlow.cs:31:18:31:21 | this access : D [field Field] : Object | | ExternalFlow.cs:30:13:30:16 | [post] this access : D [field Field] : Object | ExternalFlow.cs:31:18:31:21 | this access : D [field Field] : Object |
| ExternalFlow.cs:30:26:30:37 | object creation of type Object : Object | ExternalFlow.cs:30:13:30:16 | [post] this access : D [field Field] : Object | | ExternalFlow.cs:30:26:30:37 | object creation of type Object : Object | ExternalFlow.cs:30:13:30:16 | [post] this access : D [field Field] : Object |
| ExternalFlow.cs:31:18:31:21 | this access : D [field Field] : Object | ExternalFlow.cs:31:18:31:39 | call to method StepFieldGetter | | ExternalFlow.cs:31:18:31:21 | this access : D [field Field] : Object | ExternalFlow.cs:31:18:31:39 | call to method StepFieldGetter |
| ExternalFlow.cs:36:19:36:62 | (...) ... : Object [field Field] : Object | ExternalFlow.cs:36:18:36:69 | access to field Field | | ExternalFlow.cs:36:19:36:62 | (...) ... : D [field Field] : Object | ExternalFlow.cs:36:18:36:69 | access to field Field |
| ExternalFlow.cs:36:22:36:25 | [post] this access : D [field Field] : Object | ExternalFlow.cs:37:18:37:21 | this access : D [field Field] : Object | | ExternalFlow.cs:36:22:36:25 | [post] this access : D [field Field] : Object | ExternalFlow.cs:37:18:37:21 | this access : D [field Field] : Object |
| ExternalFlow.cs:36:22:36:55 | call to method StepFieldSetter : D [field Field2, field Field] : Object | ExternalFlow.cs:36:22:36:62 | access to field Field2 : Object [field Field] : Object | | ExternalFlow.cs:36:22:36:55 | call to method StepFieldSetter : D [field Field2, field Field] : Object | ExternalFlow.cs:36:22:36:62 | access to field Field2 : Object [field Field] : Object |
| ExternalFlow.cs:36:22:36:62 | access to field Field2 : Object [field Field] : Object | ExternalFlow.cs:36:19:36:62 | (...) ... : Object [field Field] : Object | | ExternalFlow.cs:36:22:36:62 | access to field Field2 : Object [field Field] : Object | ExternalFlow.cs:36:19:36:62 | (...) ... : D [field Field] : Object |
| ExternalFlow.cs:36:43:36:54 | object creation of type Object : Object | ExternalFlow.cs:36:22:36:25 | [post] this access : D [field Field] : Object | | ExternalFlow.cs:36:43:36:54 | object creation of type Object : Object | ExternalFlow.cs:36:22:36:25 | [post] this access : D [field Field] : Object |
| ExternalFlow.cs:36:43:36:54 | object creation of type Object : Object | ExternalFlow.cs:36:22:36:55 | call to method StepFieldSetter : D [field Field2, field Field] : Object | | ExternalFlow.cs:36:43:36:54 | object creation of type Object : Object | ExternalFlow.cs:36:22:36:55 | call to method StepFieldSetter : D [field Field2, field Field] : Object |
| ExternalFlow.cs:37:18:37:21 | this access : D [field Field] : Object | ExternalFlow.cs:37:18:37:27 | access to field Field | | ExternalFlow.cs:37:18:37:21 | this access : D [field Field] : Object | ExternalFlow.cs:37:18:37:27 | access to field Field |
@@ -38,8 +38,7 @@ edges
| ExternalFlow.cs:72:23:72:23 | o : Object | ExternalFlow.cs:72:35:72:35 | access to parameter o | | ExternalFlow.cs:72:23:72:23 | o : Object | ExternalFlow.cs:72:35:72:35 | access to parameter o |
| ExternalFlow.cs:77:24:77:58 | call to method Map<Int32,Object> : T[] [element] : Object | ExternalFlow.cs:78:18:78:21 | access to local variable objs : T[] [element] : Object | | ExternalFlow.cs:77:24:77:58 | call to method Map<Int32,Object> : T[] [element] : Object | ExternalFlow.cs:78:18:78:21 | access to local variable objs : T[] [element] : Object |
| ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | ExternalFlow.cs:77:24:77:58 | call to method Map<Int32,Object> : T[] [element] : Object | | ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | ExternalFlow.cs:77:24:77:58 | call to method Map<Int32,Object> : T[] [element] : Object |
| ExternalFlow.cs:78:18:78:21 | access to local variable objs : T[] [element] : Object | ExternalFlow.cs:78:18:78:24 | access to array element : Object | | ExternalFlow.cs:78:18:78:21 | access to local variable objs : T[] [element] : Object | ExternalFlow.cs:78:18:78:24 | access to array element |
| ExternalFlow.cs:78:18:78:24 | access to array element : Object | ExternalFlow.cs:78:18:78:24 | (...) ... |
| ExternalFlow.cs:83:30:83:45 | { ..., ... } : null [element] : Object | ExternalFlow.cs:84:29:84:32 | access to local variable objs : null [element] : Object | | ExternalFlow.cs:83:30:83:45 | { ..., ... } : null [element] : Object | ExternalFlow.cs:84:29:84:32 | access to local variable objs : null [element] : Object |
| ExternalFlow.cs:83:32:83:43 | object creation of type Object : Object | ExternalFlow.cs:83:30:83:45 | { ..., ... } : null [element] : Object | | ExternalFlow.cs:83:32:83:43 | object creation of type Object : Object | ExternalFlow.cs:83:30:83:45 | { ..., ... } : null [element] : Object |
| ExternalFlow.cs:84:25:84:41 | call to method Map<Object,Object> : T[] [element] : Object | ExternalFlow.cs:85:18:85:22 | access to local variable objs2 : T[] [element] : Object | | ExternalFlow.cs:84:25:84:41 | call to method Map<Object,Object> : T[] [element] : Object | ExternalFlow.cs:85:18:85:22 | access to local variable objs2 : T[] [element] : Object |
@@ -91,7 +90,7 @@ nodes
| ExternalFlow.cs:31:18:31:21 | this access : D [field Field] : Object | semmle.label | this access : D [field Field] : Object | | ExternalFlow.cs:31:18:31:21 | this access : D [field Field] : Object | semmle.label | this access : D [field Field] : Object |
| ExternalFlow.cs:31:18:31:39 | call to method StepFieldGetter | semmle.label | call to method StepFieldGetter | | ExternalFlow.cs:31:18:31:39 | call to method StepFieldGetter | semmle.label | call to method StepFieldGetter |
| ExternalFlow.cs:36:18:36:69 | access to field Field | semmle.label | access to field Field | | ExternalFlow.cs:36:18:36:69 | access to field Field | semmle.label | access to field Field |
| ExternalFlow.cs:36:19:36:62 | (...) ... : Object [field Field] : Object | semmle.label | (...) ... : Object [field Field] : Object | | ExternalFlow.cs:36:19:36:62 | (...) ... : D [field Field] : Object | semmle.label | (...) ... : D [field Field] : Object |
| ExternalFlow.cs:36:22:36:25 | [post] this access : D [field Field] : Object | semmle.label | [post] this access : D [field Field] : Object | | ExternalFlow.cs:36:22:36:25 | [post] this access : D [field Field] : Object | semmle.label | [post] this access : D [field Field] : Object |
| ExternalFlow.cs:36:22:36:55 | call to method StepFieldSetter : D [field Field2, field Field] : Object | semmle.label | call to method StepFieldSetter : D [field Field2, field Field] : Object | | ExternalFlow.cs:36:22:36:55 | call to method StepFieldSetter : D [field Field2, field Field] : Object | semmle.label | call to method StepFieldSetter : D [field Field2, field Field] : Object |
| ExternalFlow.cs:36:22:36:62 | access to field Field2 : Object [field Field] : Object | semmle.label | access to field Field2 : Object [field Field] : Object | | ExternalFlow.cs:36:22:36:62 | access to field Field2 : Object [field Field] : Object | semmle.label | access to field Field2 : Object [field Field] : Object |
@@ -124,8 +123,7 @@ nodes
| ExternalFlow.cs:77:24:77:58 | call to method Map<Int32,Object> : T[] [element] : Object | semmle.label | call to method Map<Int32,Object> : T[] [element] : Object | | ExternalFlow.cs:77:24:77:58 | call to method Map<Int32,Object> : T[] [element] : Object | semmle.label | call to method Map<Int32,Object> : T[] [element] : Object |
| ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | semmle.label | object creation of type Object : Object |
| ExternalFlow.cs:78:18:78:21 | access to local variable objs : T[] [element] : Object | semmle.label | access to local variable objs : T[] [element] : Object | | ExternalFlow.cs:78:18:78:21 | access to local variable objs : T[] [element] : Object | semmle.label | access to local variable objs : T[] [element] : Object |
| ExternalFlow.cs:78:18:78:24 | (...) ... | semmle.label | (...) ... | | ExternalFlow.cs:78:18:78:24 | access to array element | semmle.label | access to array element |
| ExternalFlow.cs:78:18:78:24 | access to array element : Object | semmle.label | access to array element : Object |
| ExternalFlow.cs:83:30:83:45 | { ..., ... } : null [element] : Object | semmle.label | { ..., ... } : null [element] : Object | | ExternalFlow.cs:83:30:83:45 | { ..., ... } : null [element] : Object | semmle.label | { ..., ... } : null [element] : Object |
| ExternalFlow.cs:83:32:83:43 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | ExternalFlow.cs:83:32:83:43 | object creation of type Object : Object | semmle.label | object creation of type Object : Object |
| ExternalFlow.cs:84:25:84:41 | call to method Map<Object,Object> : T[] [element] : Object | semmle.label | call to method Map<Object,Object> : T[] [element] : Object | | ExternalFlow.cs:84:25:84:41 | call to method Map<Object,Object> : T[] [element] : Object | semmle.label | call to method Map<Object,Object> : T[] [element] : Object |
@@ -184,7 +182,7 @@ subpaths
| ExternalFlow.cs:60:47:60:47 | access to parameter o | ExternalFlow.cs:60:64:60:75 | object creation of type Object : Object | ExternalFlow.cs:60:47:60:47 | access to parameter o | $@ | ExternalFlow.cs:60:64:60:75 | object creation of type Object : Object | object creation of type Object : Object | | ExternalFlow.cs:60:47:60:47 | access to parameter o | ExternalFlow.cs:60:64:60:75 | object creation of type Object : Object | ExternalFlow.cs:60:47:60:47 | access to parameter o | $@ | ExternalFlow.cs:60:64:60:75 | object creation of type Object : Object | object creation of type Object : Object |
| ExternalFlow.cs:66:18:66:18 | access to local variable o | ExternalFlow.cs:65:45:65:56 | object creation of type Object : Object | ExternalFlow.cs:66:18:66:18 | access to local variable o | $@ | ExternalFlow.cs:65:45:65:56 | object creation of type Object : Object | object creation of type Object : Object | | ExternalFlow.cs:66:18:66:18 | access to local variable o | ExternalFlow.cs:65:45:65:56 | object creation of type Object : Object | ExternalFlow.cs:66:18:66:18 | access to local variable o | $@ | ExternalFlow.cs:65:45:65:56 | object creation of type Object : Object | object creation of type Object : Object |
| ExternalFlow.cs:72:35:72:35 | access to parameter o | ExternalFlow.cs:71:32:71:43 | object creation of type Object : Object | ExternalFlow.cs:72:35:72:35 | access to parameter o | $@ | ExternalFlow.cs:71:32:71:43 | object creation of type Object : Object | object creation of type Object : Object | | ExternalFlow.cs:72:35:72:35 | access to parameter o | ExternalFlow.cs:71:32:71:43 | object creation of type Object : Object | ExternalFlow.cs:72:35:72:35 | access to parameter o | $@ | ExternalFlow.cs:71:32:71:43 | object creation of type Object : Object | object creation of type Object : Object |
| ExternalFlow.cs:78:18:78:24 | (...) ... | ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | ExternalFlow.cs:78:18:78:24 | (...) ... | $@ | ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | object creation of type Object : Object | | ExternalFlow.cs:78:18:78:24 | access to array element | ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | ExternalFlow.cs:78:18:78:24 | access to array element | $@ | ExternalFlow.cs:77:46:77:57 | object creation of type Object : Object | object creation of type Object : Object |
| ExternalFlow.cs:85:18:85:25 | access to array element | ExternalFlow.cs:83:32:83:43 | object creation of type Object : Object | ExternalFlow.cs:85:18:85:25 | access to array element | $@ | ExternalFlow.cs:83:32:83:43 | object creation of type Object : Object | object creation of type Object : Object | | ExternalFlow.cs:85:18:85:25 | access to array element | ExternalFlow.cs:83:32:83:43 | object creation of type Object : Object | ExternalFlow.cs:85:18:85:25 | access to array element | $@ | ExternalFlow.cs:83:32:83:43 | object creation of type Object : Object | object creation of type Object : Object |
| ExternalFlow.cs:92:18:92:18 | (...) ... | ExternalFlow.cs:90:21:90:34 | object creation of type String : String | ExternalFlow.cs:92:18:92:18 | (...) ... | $@ | ExternalFlow.cs:90:21:90:34 | object creation of type String : String | object creation of type String : String | | ExternalFlow.cs:92:18:92:18 | (...) ... | ExternalFlow.cs:90:21:90:34 | object creation of type String : String | ExternalFlow.cs:92:18:92:18 | (...) ... | $@ | ExternalFlow.cs:90:21:90:34 | object creation of type String : String | object creation of type String : String |
| ExternalFlow.cs:102:22:102:22 | access to parameter d | ExternalFlow.cs:98:24:98:35 | object creation of type Object : Object | ExternalFlow.cs:102:22:102:22 | access to parameter d | $@ | ExternalFlow.cs:98:24:98:35 | object creation of type Object : Object | object creation of type Object : Object | | ExternalFlow.cs:102:22:102:22 | access to parameter d | ExternalFlow.cs:98:24:98:35 | object creation of type Object : Object | ExternalFlow.cs:102:22:102:22 | access to parameter d | $@ | ExternalFlow.cs:98:24:98:35 | object creation of type Object : Object | object creation of type Object : Object |

View File

@@ -16,8 +16,8 @@ extensions:
- ["My.Qltest", "D", false, "StepElementSetter", "(System.Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["My.Qltest", "D", false, "StepElementSetter", "(System.Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"]
- ["My.Qltest", "D", false, "Apply<,>", "(System.Func<S,T>,S)", "", "Argument[1]", "Argument[0].Parameter[0]", "value", "manual"] - ["My.Qltest", "D", false, "Apply<,>", "(System.Func<S,T>,S)", "", "Argument[1]", "Argument[0].Parameter[0]", "value", "manual"]
- ["My.Qltest", "D", false, "Apply<,>", "(System.Func<S,T>,S)", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"] - ["My.Qltest", "D", false, "Apply<,>", "(System.Func<S,T>,S)", "", "Argument[0].ReturnValue", "ReturnValue", "value", "manual"]
- ["My.Qltest", "D", false, "Apply2<>", "(System.Action<S>,S,S)", "", "Argument[1].Field[My.Qltest.D.Field]", "Argument[0].Parameter[0]", "value", "manual"] - ["My.Qltest", "D", false, "Apply2", "(System.Action<System.Object>,My.Qltest.D,My.Qltest.D)", "", "Argument[1].Field[My.Qltest.D.Field]", "Argument[0].Parameter[0]", "value", "manual"]
- ["My.Qltest", "D", false, "Apply2<>", "(System.Action<S>,S,S)", "", "Argument[2].Field[My.Qltest.D.Field2]", "Argument[0].Parameter[0]", "value", "manual"] - ["My.Qltest", "D", false, "Apply2", "(System.Action<System.Object>,My.Qltest.D,My.Qltest.D)", "", "Argument[2].Field[My.Qltest.D.Field2]", "Argument[0].Parameter[0]", "value", "manual"]
- ["My.Qltest", "D", false, "Map<,>", "(S[],System.Func<S,T>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"] - ["My.Qltest", "D", false, "Map<,>", "(S[],System.Func<S,T>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
- ["My.Qltest", "D", false, "Map<,>", "(S[],System.Func<S,T>)", "", "Argument[1].ReturnValue", "ReturnValue.Element", "value", "manual"] - ["My.Qltest", "D", false, "Map<,>", "(S[],System.Func<S,T>)", "", "Argument[1].ReturnValue", "ReturnValue.Element", "value", "manual"]
- ["My.Qltest", "D", false, "Parse", "(System.String,System.Int32)", "", "Argument[0]", "Argument[1]", "taint", "manual"] - ["My.Qltest", "D", false, "Parse", "(System.String,System.Int32)", "", "Argument[0]", "Argument[1]", "taint", "manual"]

View File

@@ -267,7 +267,7 @@ edges
| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:31:514:32 | [post] access to local variable y1 : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:31:514:32 | [post] access to local variable y1 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:36:514:37 | [post] access to local variable y2 : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:36:514:37 | [post] access to local variable y2 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:42:514:43 | [post] access to local variable y3 : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:42:514:43 | [post] access to local variable y3 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SubSimpleClass [field field] : String |
| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String |
| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:544:20:544:20 | [post] access to local variable x : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:544:20:544:20 | [post] access to local variable x : SimpleClass [field field] : String |
@@ -286,8 +286,8 @@ edges
| GlobalDataFlow.cs:515:15:515:16 | access to local variable y1 : SimpleClass [field field] : String | GlobalDataFlow.cs:515:15:515:22 | access to field field | | GlobalDataFlow.cs:515:15:515:16 | access to local variable y1 : SimpleClass [field field] : String | GlobalDataFlow.cs:515:15:515:22 | access to field field |
| GlobalDataFlow.cs:516:15:516:16 | access to local variable y2 : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:22 | access to field field | | GlobalDataFlow.cs:516:15:516:16 | access to local variable y2 : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:22 | access to field field |
| GlobalDataFlow.cs:517:15:517:16 | access to local variable y3 : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:22 | access to field field | | GlobalDataFlow.cs:517:15:517:16 | access to local variable y3 : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:22 | access to field field |
| GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SimpleClass [field field] : String | | GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SubSimpleClass [field field] : String |
| GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:21 | access to field field | | GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:21 | access to field field |
| GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:15 | access to parameter x : SimpleClass [field field] : String | | GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:15 | access to parameter x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:534:15:534:15 | access to local variable y : SimpleClass [field field] : String | | GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:534:15:534:15 | access to local variable y : SimpleClass [field field] : String |
| GlobalDataFlow.cs:533:15:533:15 | access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:21 | access to field field | | GlobalDataFlow.cs:533:15:533:15 | access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:21 | access to field field |
@@ -579,8 +579,8 @@ nodes
| GlobalDataFlow.cs:516:15:516:22 | access to field field | semmle.label | access to field field | | GlobalDataFlow.cs:516:15:516:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:517:15:517:16 | access to local variable y3 : SimpleClass [field field] : String | semmle.label | access to local variable y3 : SimpleClass [field field] : String | | GlobalDataFlow.cs:517:15:517:16 | access to local variable y3 : SimpleClass [field field] : String | semmle.label | access to local variable y3 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:517:15:517:22 | access to field field | semmle.label | access to field field | | GlobalDataFlow.cs:517:15:517:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SimpleClass [field field] : String | semmle.label | [post] access to local variable x : SimpleClass [field field] : String | | GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SubSimpleClass [field field] : String | semmle.label | [post] access to local variable x : SubSimpleClass [field field] : String |
| GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String | | GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SubSimpleClass [field field] : String | semmle.label | access to local variable x : SubSimpleClass [field field] : String |
| GlobalDataFlow.cs:526:15:526:21 | access to field field | semmle.label | access to field field | | GlobalDataFlow.cs:526:15:526:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | semmle.label | [post] access to parameter x : SimpleClass [field field] : String | | GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | semmle.label | [post] access to parameter x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | semmle.label | [post] access to local variable y : SimpleClass [field field] : String | | GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | semmle.label | [post] access to local variable y : SimpleClass [field field] : String |

View File

@@ -293,7 +293,7 @@ edges
| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:31:514:32 | [post] access to local variable y1 : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:31:514:32 | [post] access to local variable y1 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:36:514:37 | [post] access to local variable y2 : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:36:514:37 | [post] access to local variable y2 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:42:514:43 | [post] access to local variable y3 : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:514:42:514:43 | [post] access to local variable y3 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SubSimpleClass [field field] : String |
| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String |
| GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:544:20:544:20 | [post] access to local variable x : SimpleClass [field field] : String | | GlobalDataFlow.cs:500:9:500:10 | [post] access to parameter sc : SimpleClass [field field] : String | GlobalDataFlow.cs:544:20:544:20 | [post] access to local variable x : SimpleClass [field field] : String |
@@ -312,8 +312,8 @@ edges
| GlobalDataFlow.cs:515:15:515:16 | access to local variable y1 : SimpleClass [field field] : String | GlobalDataFlow.cs:515:15:515:22 | access to field field | | GlobalDataFlow.cs:515:15:515:16 | access to local variable y1 : SimpleClass [field field] : String | GlobalDataFlow.cs:515:15:515:22 | access to field field |
| GlobalDataFlow.cs:516:15:516:16 | access to local variable y2 : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:22 | access to field field | | GlobalDataFlow.cs:516:15:516:16 | access to local variable y2 : SimpleClass [field field] : String | GlobalDataFlow.cs:516:15:516:22 | access to field field |
| GlobalDataFlow.cs:517:15:517:16 | access to local variable y3 : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:22 | access to field field | | GlobalDataFlow.cs:517:15:517:16 | access to local variable y3 : SimpleClass [field field] : String | GlobalDataFlow.cs:517:15:517:22 | access to field field |
| GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SimpleClass [field field] : String | | GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SubSimpleClass [field field] : String |
| GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:21 | access to field field | | GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SubSimpleClass [field field] : String | GlobalDataFlow.cs:526:15:526:21 | access to field field |
| GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:15 | access to parameter x : SimpleClass [field field] : String | | GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:15 | access to parameter x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:534:15:534:15 | access to local variable y : SimpleClass [field field] : String | | GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | GlobalDataFlow.cs:534:15:534:15 | access to local variable y : SimpleClass [field field] : String |
| GlobalDataFlow.cs:533:15:533:15 | access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:21 | access to field field | | GlobalDataFlow.cs:533:15:533:15 | access to parameter x : SimpleClass [field field] : String | GlobalDataFlow.cs:533:15:533:21 | access to field field |
@@ -633,8 +633,8 @@ nodes
| GlobalDataFlow.cs:516:15:516:22 | access to field field | semmle.label | access to field field | | GlobalDataFlow.cs:516:15:516:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:517:15:517:16 | access to local variable y3 : SimpleClass [field field] : String | semmle.label | access to local variable y3 : SimpleClass [field field] : String | | GlobalDataFlow.cs:517:15:517:16 | access to local variable y3 : SimpleClass [field field] : String | semmle.label | access to local variable y3 : SimpleClass [field field] : String |
| GlobalDataFlow.cs:517:15:517:22 | access to field field | semmle.label | access to field field | | GlobalDataFlow.cs:517:15:517:22 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SimpleClass [field field] : String | semmle.label | [post] access to local variable x : SimpleClass [field field] : String | | GlobalDataFlow.cs:525:33:525:33 | [post] access to local variable x : SubSimpleClass [field field] : String | semmle.label | [post] access to local variable x : SubSimpleClass [field field] : String |
| GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SimpleClass [field field] : String | semmle.label | access to local variable x : SimpleClass [field field] : String | | GlobalDataFlow.cs:526:15:526:15 | access to local variable x : SubSimpleClass [field field] : String | semmle.label | access to local variable x : SubSimpleClass [field field] : String |
| GlobalDataFlow.cs:526:15:526:21 | access to field field | semmle.label | access to field field | | GlobalDataFlow.cs:526:15:526:21 | access to field field | semmle.label | access to field field |
| GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | semmle.label | [post] access to parameter x : SimpleClass [field field] : String | | GlobalDataFlow.cs:532:20:532:20 | [post] access to parameter x : SimpleClass [field field] : String | semmle.label | [post] access to parameter x : SimpleClass [field field] : String |
| GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | semmle.label | [post] access to local variable y : SimpleClass [field field] : String | | GlobalDataFlow.cs:532:25:532:25 | [post] access to local variable y : SimpleClass [field field] : String | semmle.label | [post] access to local variable y : SimpleClass [field field] : String |

View File

@@ -74,14 +74,14 @@ edges
| EntityFramework.cs:196:13:196:23 | [post] access to property Persons : DbSet<T> [element, property Name] : String | EntityFramework.cs:196:13:196:15 | [post] access to local variable ctx : MyContext [property Persons, element, property Name] : String | | EntityFramework.cs:196:13:196:23 | [post] access to property Persons : DbSet<T> [element, property Name] : String | EntityFramework.cs:196:13:196:15 | [post] access to local variable ctx : MyContext [property Persons, element, property Name] : String |
| EntityFramework.cs:196:29:196:29 | access to parameter p : Person [property Name] : String | EntityFramework.cs:196:13:196:23 | [post] access to property Persons : DbSet<T> [element, property Name] : String | | EntityFramework.cs:196:29:196:29 | access to parameter p : Person [property Name] : String | EntityFramework.cs:196:13:196:23 | [post] access to property Persons : DbSet<T> [element, property Name] : String |
| EntityFramework.cs:197:13:197:15 | access to local variable ctx : MyContext [property Persons, element, property Name] : String | EntityFramework.cs:204:18:204:28 | access to property Persons : DbSet<Person> [element, property Name] : String | | EntityFramework.cs:197:13:197:15 | access to local variable ctx : MyContext [property Persons, element, property Name] : String | EntityFramework.cs:204:18:204:28 | access to property Persons : DbSet<Person> [element, property Name] : String |
| EntityFramework.cs:204:18:204:28 | access to property Persons : DbSet<Person> [element, property Name] : String | EntityFramework.cs:204:18:204:36 | call to method First<Person> : Object [property Name] : String | | EntityFramework.cs:204:18:204:28 | access to property Persons : DbSet<Person> [element, property Name] : String | EntityFramework.cs:204:18:204:36 | call to method First<Person> : Person [property Name] : String |
| EntityFramework.cs:204:18:204:36 | call to method First<Person> : Object [property Name] : String | EntityFramework.cs:204:18:204:41 | access to property Name | | EntityFramework.cs:204:18:204:36 | call to method First<Person> : Person [property Name] : String | EntityFramework.cs:204:18:204:41 | access to property Name |
| EntityFramework.cs:212:18:212:30 | access to property Addresses : DbSet<Address> [element, property Street] : String | EntityFramework.cs:212:18:212:38 | call to method First<Address> : Object [property Street] : String | | EntityFramework.cs:212:18:212:30 | access to property Addresses : DbSet<Address> [element, property Street] : String | EntityFramework.cs:212:18:212:38 | call to method First<Address> : Address [property Street] : String |
| EntityFramework.cs:212:18:212:38 | call to method First<Address> : Object [property Street] : String | EntityFramework.cs:212:18:212:45 | access to property Street | | EntityFramework.cs:212:18:212:38 | call to method First<Address> : Address [property Street] : String | EntityFramework.cs:212:18:212:45 | access to property Street |
| EntityFramework.cs:219:18:219:28 | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | EntityFramework.cs:219:18:219:36 | call to method First<Person> : Object [property Addresses, element, property Street] : String | | EntityFramework.cs:219:18:219:28 | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | EntityFramework.cs:219:18:219:36 | call to method First<Person> : Person [property Addresses, element, property Street] : String |
| EntityFramework.cs:219:18:219:36 | call to method First<Person> : Object [property Addresses, element, property Street] : String | EntityFramework.cs:219:18:219:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | | EntityFramework.cs:219:18:219:36 | call to method First<Person> : Person [property Addresses, element, property Street] : String | EntityFramework.cs:219:18:219:46 | access to property Addresses : ICollection<Address> [element, property Street] : String |
| EntityFramework.cs:219:18:219:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | EntityFramework.cs:219:18:219:54 | call to method First<Address> : Object [property Street] : String | | EntityFramework.cs:219:18:219:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | EntityFramework.cs:219:18:219:54 | call to method First<Address> : Address [property Street] : String |
| EntityFramework.cs:219:18:219:54 | call to method First<Address> : Object [property Street] : String | EntityFramework.cs:219:18:219:61 | access to property Street | | EntityFramework.cs:219:18:219:54 | call to method First<Address> : Address [property Street] : String | EntityFramework.cs:219:18:219:61 | access to property Street |
| EntityFrameworkCore.cs:82:31:82:39 | "tainted" : String | EntityFrameworkCore.cs:83:18:83:28 | access to local variable taintSource | | EntityFrameworkCore.cs:82:31:82:39 | "tainted" : String | EntityFrameworkCore.cs:83:18:83:28 | access to local variable taintSource |
| EntityFrameworkCore.cs:82:31:82:39 | "tainted" : String | EntityFrameworkCore.cs:84:35:84:45 | access to local variable taintSource : String | | EntityFrameworkCore.cs:82:31:82:39 | "tainted" : String | EntityFrameworkCore.cs:84:35:84:45 | access to local variable taintSource : String |
| EntityFrameworkCore.cs:82:31:82:39 | "tainted" : String | EntityFrameworkCore.cs:85:18:85:42 | (...) ... | | EntityFrameworkCore.cs:82:31:82:39 | "tainted" : String | EntityFrameworkCore.cs:85:18:85:42 | (...) ... |
@@ -165,14 +165,14 @@ edges
| EntityFrameworkCore.cs:229:13:229:23 | [post] access to property Persons : DbSet<T> [element, property Name] : String | EntityFrameworkCore.cs:229:13:229:15 | [post] access to local variable ctx : MyContext [property Persons, element, property Name] : String | | EntityFrameworkCore.cs:229:13:229:23 | [post] access to property Persons : DbSet<T> [element, property Name] : String | EntityFrameworkCore.cs:229:13:229:15 | [post] access to local variable ctx : MyContext [property Persons, element, property Name] : String |
| EntityFrameworkCore.cs:229:29:229:29 | access to parameter p : Person [property Name] : String | EntityFrameworkCore.cs:229:13:229:23 | [post] access to property Persons : DbSet<T> [element, property Name] : String | | EntityFrameworkCore.cs:229:29:229:29 | access to parameter p : Person [property Name] : String | EntityFrameworkCore.cs:229:13:229:23 | [post] access to property Persons : DbSet<T> [element, property Name] : String |
| EntityFrameworkCore.cs:230:13:230:15 | access to local variable ctx : MyContext [property Persons, element, property Name] : String | EntityFrameworkCore.cs:237:18:237:28 | access to property Persons : DbSet<Person> [element, property Name] : String | | EntityFrameworkCore.cs:230:13:230:15 | access to local variable ctx : MyContext [property Persons, element, property Name] : String | EntityFrameworkCore.cs:237:18:237:28 | access to property Persons : DbSet<Person> [element, property Name] : String |
| EntityFrameworkCore.cs:237:18:237:28 | access to property Persons : DbSet<Person> [element, property Name] : String | EntityFrameworkCore.cs:237:18:237:36 | call to method First<Person> : Object [property Name] : String | | EntityFrameworkCore.cs:237:18:237:28 | access to property Persons : DbSet<Person> [element, property Name] : String | EntityFrameworkCore.cs:237:18:237:36 | call to method First<Person> : Person [property Name] : String |
| EntityFrameworkCore.cs:237:18:237:36 | call to method First<Person> : Object [property Name] : String | EntityFrameworkCore.cs:237:18:237:41 | access to property Name | | EntityFrameworkCore.cs:237:18:237:36 | call to method First<Person> : Person [property Name] : String | EntityFrameworkCore.cs:237:18:237:41 | access to property Name |
| EntityFrameworkCore.cs:245:18:245:30 | access to property Addresses : DbSet<Address> [element, property Street] : String | EntityFrameworkCore.cs:245:18:245:38 | call to method First<Address> : Object [property Street] : String | | EntityFrameworkCore.cs:245:18:245:30 | access to property Addresses : DbSet<Address> [element, property Street] : String | EntityFrameworkCore.cs:245:18:245:38 | call to method First<Address> : Address [property Street] : String |
| EntityFrameworkCore.cs:245:18:245:38 | call to method First<Address> : Object [property Street] : String | EntityFrameworkCore.cs:245:18:245:45 | access to property Street | | EntityFrameworkCore.cs:245:18:245:38 | call to method First<Address> : Address [property Street] : String | EntityFrameworkCore.cs:245:18:245:45 | access to property Street |
| EntityFrameworkCore.cs:252:18:252:28 | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | EntityFrameworkCore.cs:252:18:252:36 | call to method First<Person> : Object [property Addresses, element, property Street] : String | | EntityFrameworkCore.cs:252:18:252:28 | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | EntityFrameworkCore.cs:252:18:252:36 | call to method First<Person> : Person [property Addresses, element, property Street] : String |
| EntityFrameworkCore.cs:252:18:252:36 | call to method First<Person> : Object [property Addresses, element, property Street] : String | EntityFrameworkCore.cs:252:18:252:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | | EntityFrameworkCore.cs:252:18:252:36 | call to method First<Person> : Person [property Addresses, element, property Street] : String | EntityFrameworkCore.cs:252:18:252:46 | access to property Addresses : ICollection<Address> [element, property Street] : String |
| EntityFrameworkCore.cs:252:18:252:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | EntityFrameworkCore.cs:252:18:252:54 | call to method First<Address> : Object [property Street] : String | | EntityFrameworkCore.cs:252:18:252:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | EntityFrameworkCore.cs:252:18:252:54 | call to method First<Address> : Address [property Street] : String |
| EntityFrameworkCore.cs:252:18:252:54 | call to method First<Address> : Object [property Street] : String | EntityFrameworkCore.cs:252:18:252:61 | access to property Street | | EntityFrameworkCore.cs:252:18:252:54 | call to method First<Address> : Address [property Street] : String | EntityFrameworkCore.cs:252:18:252:61 | access to property Street |
nodes nodes
| EntityFramework.cs:59:13:62:13 | { ..., ... } : Person [property Name] : String | semmle.label | { ..., ... } : Person [property Name] : String | | EntityFramework.cs:59:13:62:13 | { ..., ... } : Person [property Name] : String | semmle.label | { ..., ... } : Person [property Name] : String |
| EntityFramework.cs:61:24:61:32 | "tainted" : String | semmle.label | "tainted" : String | | EntityFramework.cs:61:24:61:32 | "tainted" : String | semmle.label | "tainted" : String |
@@ -237,15 +237,15 @@ nodes
| EntityFramework.cs:196:29:196:29 | access to parameter p : Person [property Name] : String | semmle.label | access to parameter p : Person [property Name] : String | | EntityFramework.cs:196:29:196:29 | access to parameter p : Person [property Name] : String | semmle.label | access to parameter p : Person [property Name] : String |
| EntityFramework.cs:197:13:197:15 | access to local variable ctx : MyContext [property Persons, element, property Name] : String | semmle.label | access to local variable ctx : MyContext [property Persons, element, property Name] : String | | EntityFramework.cs:197:13:197:15 | access to local variable ctx : MyContext [property Persons, element, property Name] : String | semmle.label | access to local variable ctx : MyContext [property Persons, element, property Name] : String |
| EntityFramework.cs:204:18:204:28 | access to property Persons : DbSet<Person> [element, property Name] : String | semmle.label | access to property Persons : DbSet<Person> [element, property Name] : String | | EntityFramework.cs:204:18:204:28 | access to property Persons : DbSet<Person> [element, property Name] : String | semmle.label | access to property Persons : DbSet<Person> [element, property Name] : String |
| EntityFramework.cs:204:18:204:36 | call to method First<Person> : Object [property Name] : String | semmle.label | call to method First<Person> : Object [property Name] : String | | EntityFramework.cs:204:18:204:36 | call to method First<Person> : Person [property Name] : String | semmle.label | call to method First<Person> : Person [property Name] : String |
| EntityFramework.cs:204:18:204:41 | access to property Name | semmle.label | access to property Name | | EntityFramework.cs:204:18:204:41 | access to property Name | semmle.label | access to property Name |
| EntityFramework.cs:212:18:212:30 | access to property Addresses : DbSet<Address> [element, property Street] : String | semmle.label | access to property Addresses : DbSet<Address> [element, property Street] : String | | EntityFramework.cs:212:18:212:30 | access to property Addresses : DbSet<Address> [element, property Street] : String | semmle.label | access to property Addresses : DbSet<Address> [element, property Street] : String |
| EntityFramework.cs:212:18:212:38 | call to method First<Address> : Object [property Street] : String | semmle.label | call to method First<Address> : Object [property Street] : String | | EntityFramework.cs:212:18:212:38 | call to method First<Address> : Address [property Street] : String | semmle.label | call to method First<Address> : Address [property Street] : String |
| EntityFramework.cs:212:18:212:45 | access to property Street | semmle.label | access to property Street | | EntityFramework.cs:212:18:212:45 | access to property Street | semmle.label | access to property Street |
| EntityFramework.cs:219:18:219:28 | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | semmle.label | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | | EntityFramework.cs:219:18:219:28 | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | semmle.label | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String |
| EntityFramework.cs:219:18:219:36 | call to method First<Person> : Object [property Addresses, element, property Street] : String | semmle.label | call to method First<Person> : Object [property Addresses, element, property Street] : String | | EntityFramework.cs:219:18:219:36 | call to method First<Person> : Person [property Addresses, element, property Street] : String | semmle.label | call to method First<Person> : Person [property Addresses, element, property Street] : String |
| EntityFramework.cs:219:18:219:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | semmle.label | access to property Addresses : ICollection<Address> [element, property Street] : String | | EntityFramework.cs:219:18:219:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | semmle.label | access to property Addresses : ICollection<Address> [element, property Street] : String |
| EntityFramework.cs:219:18:219:54 | call to method First<Address> : Object [property Street] : String | semmle.label | call to method First<Address> : Object [property Street] : String | | EntityFramework.cs:219:18:219:54 | call to method First<Address> : Address [property Street] : String | semmle.label | call to method First<Address> : Address [property Street] : String |
| EntityFramework.cs:219:18:219:61 | access to property Street | semmle.label | access to property Street | | EntityFramework.cs:219:18:219:61 | access to property Street | semmle.label | access to property Street |
| EntityFrameworkCore.cs:82:31:82:39 | "tainted" : String | semmle.label | "tainted" : String | | EntityFrameworkCore.cs:82:31:82:39 | "tainted" : String | semmle.label | "tainted" : String |
| EntityFrameworkCore.cs:83:18:83:28 | access to local variable taintSource | semmle.label | access to local variable taintSource | | EntityFrameworkCore.cs:83:18:83:28 | access to local variable taintSource | semmle.label | access to local variable taintSource |
@@ -318,15 +318,15 @@ nodes
| EntityFrameworkCore.cs:229:29:229:29 | access to parameter p : Person [property Name] : String | semmle.label | access to parameter p : Person [property Name] : String | | EntityFrameworkCore.cs:229:29:229:29 | access to parameter p : Person [property Name] : String | semmle.label | access to parameter p : Person [property Name] : String |
| EntityFrameworkCore.cs:230:13:230:15 | access to local variable ctx : MyContext [property Persons, element, property Name] : String | semmle.label | access to local variable ctx : MyContext [property Persons, element, property Name] : String | | EntityFrameworkCore.cs:230:13:230:15 | access to local variable ctx : MyContext [property Persons, element, property Name] : String | semmle.label | access to local variable ctx : MyContext [property Persons, element, property Name] : String |
| EntityFrameworkCore.cs:237:18:237:28 | access to property Persons : DbSet<Person> [element, property Name] : String | semmle.label | access to property Persons : DbSet<Person> [element, property Name] : String | | EntityFrameworkCore.cs:237:18:237:28 | access to property Persons : DbSet<Person> [element, property Name] : String | semmle.label | access to property Persons : DbSet<Person> [element, property Name] : String |
| EntityFrameworkCore.cs:237:18:237:36 | call to method First<Person> : Object [property Name] : String | semmle.label | call to method First<Person> : Object [property Name] : String | | EntityFrameworkCore.cs:237:18:237:36 | call to method First<Person> : Person [property Name] : String | semmle.label | call to method First<Person> : Person [property Name] : String |
| EntityFrameworkCore.cs:237:18:237:41 | access to property Name | semmle.label | access to property Name | | EntityFrameworkCore.cs:237:18:237:41 | access to property Name | semmle.label | access to property Name |
| EntityFrameworkCore.cs:245:18:245:30 | access to property Addresses : DbSet<Address> [element, property Street] : String | semmle.label | access to property Addresses : DbSet<Address> [element, property Street] : String | | EntityFrameworkCore.cs:245:18:245:30 | access to property Addresses : DbSet<Address> [element, property Street] : String | semmle.label | access to property Addresses : DbSet<Address> [element, property Street] : String |
| EntityFrameworkCore.cs:245:18:245:38 | call to method First<Address> : Object [property Street] : String | semmle.label | call to method First<Address> : Object [property Street] : String | | EntityFrameworkCore.cs:245:18:245:38 | call to method First<Address> : Address [property Street] : String | semmle.label | call to method First<Address> : Address [property Street] : String |
| EntityFrameworkCore.cs:245:18:245:45 | access to property Street | semmle.label | access to property Street | | EntityFrameworkCore.cs:245:18:245:45 | access to property Street | semmle.label | access to property Street |
| EntityFrameworkCore.cs:252:18:252:28 | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | semmle.label | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | | EntityFrameworkCore.cs:252:18:252:28 | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String | semmle.label | access to property Persons : DbSet<Person> [element, property Addresses, element, property Street] : String |
| EntityFrameworkCore.cs:252:18:252:36 | call to method First<Person> : Object [property Addresses, element, property Street] : String | semmle.label | call to method First<Person> : Object [property Addresses, element, property Street] : String | | EntityFrameworkCore.cs:252:18:252:36 | call to method First<Person> : Person [property Addresses, element, property Street] : String | semmle.label | call to method First<Person> : Person [property Addresses, element, property Street] : String |
| EntityFrameworkCore.cs:252:18:252:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | semmle.label | access to property Addresses : ICollection<Address> [element, property Street] : String | | EntityFrameworkCore.cs:252:18:252:46 | access to property Addresses : ICollection<Address> [element, property Street] : String | semmle.label | access to property Addresses : ICollection<Address> [element, property Street] : String |
| EntityFrameworkCore.cs:252:18:252:54 | call to method First<Address> : Object [property Street] : String | semmle.label | call to method First<Address> : Object [property Street] : String | | EntityFrameworkCore.cs:252:18:252:54 | call to method First<Address> : Address [property Street] : String | semmle.label | call to method First<Address> : Address [property Street] : String |
| EntityFrameworkCore.cs:252:18:252:61 | access to property Street | semmle.label | access to property Street | | EntityFrameworkCore.cs:252:18:252:61 | access to property Street | semmle.label | access to property Street |
subpaths subpaths
#select #select

View File

@@ -1,10 +1,10 @@
edges edges
| InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data : Byte[] [element] : Int32 | InsecureRandomness.cs:29:57:29:60 | access to local variable data : Byte[] [element] : Int32 | | InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data : Byte[] [element] : Byte | InsecureRandomness.cs:29:57:29:60 | access to local variable data : Byte[] [element] : Byte |
| InsecureRandomness.cs:28:23:28:43 | (...) ... : Int32 | InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data : Byte[] [element] : Int32 | | InsecureRandomness.cs:28:23:28:43 | (...) ... : Byte | InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data : Byte[] [element] : Byte |
| InsecureRandomness.cs:28:29:28:43 | call to method Next : Int32 | InsecureRandomness.cs:28:23:28:43 | (...) ... : Int32 | | InsecureRandomness.cs:28:29:28:43 | call to method Next : Int32 | InsecureRandomness.cs:28:23:28:43 | (...) ... : Byte |
| InsecureRandomness.cs:29:13:29:18 | [post] access to local variable result : StringBuilder [element] : String | InsecureRandomness.cs:31:16:31:21 | access to local variable result : StringBuilder [element] : String | | InsecureRandomness.cs:29:13:29:18 | [post] access to local variable result : StringBuilder [element] : String | InsecureRandomness.cs:31:16:31:21 | access to local variable result : StringBuilder [element] : String |
| InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | InsecureRandomness.cs:29:13:29:18 | [post] access to local variable result : StringBuilder [element] : String | | InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | InsecureRandomness.cs:29:13:29:18 | [post] access to local variable result : StringBuilder [element] : String |
| InsecureRandomness.cs:29:57:29:60 | access to local variable data : Byte[] [element] : Int32 | InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | | InsecureRandomness.cs:29:57:29:60 | access to local variable data : Byte[] [element] : Byte | InsecureRandomness.cs:29:27:29:61 | call to method GetString : String |
| InsecureRandomness.cs:31:16:31:21 | access to local variable result : StringBuilder [element] : String | InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | | InsecureRandomness.cs:31:16:31:21 | access to local variable result : StringBuilder [element] : String | InsecureRandomness.cs:31:16:31:32 | call to method ToString : String |
| InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | | InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString |
| InsecureRandomness.cs:60:31:60:39 | call to method Next : Int32 | InsecureRandomness.cs:62:16:62:21 | access to local variable result : String | | InsecureRandomness.cs:60:31:60:39 | call to method Next : Int32 | InsecureRandomness.cs:62:16:62:21 | access to local variable result : String |
@@ -16,12 +16,12 @@ nodes
| InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | semmle.label | call to method InsecureRandomString | | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | semmle.label | call to method InsecureRandomString |
| InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | semmle.label | call to method InsecureRandomStringFromSelection | | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | semmle.label | call to method InsecureRandomStringFromSelection |
| InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | semmle.label | call to method InsecureRandomStringFromIndexer | | InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | semmle.label | call to method InsecureRandomStringFromIndexer |
| InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data : Byte[] [element] : Int32 | semmle.label | [post] access to local variable data : Byte[] [element] : Int32 | | InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data : Byte[] [element] : Byte | semmle.label | [post] access to local variable data : Byte[] [element] : Byte |
| InsecureRandomness.cs:28:23:28:43 | (...) ... : Int32 | semmle.label | (...) ... : Int32 | | InsecureRandomness.cs:28:23:28:43 | (...) ... : Byte | semmle.label | (...) ... : Byte |
| InsecureRandomness.cs:28:29:28:43 | call to method Next : Int32 | semmle.label | call to method Next : Int32 | | InsecureRandomness.cs:28:29:28:43 | call to method Next : Int32 | semmle.label | call to method Next : Int32 |
| InsecureRandomness.cs:29:13:29:18 | [post] access to local variable result : StringBuilder [element] : String | semmle.label | [post] access to local variable result : StringBuilder [element] : String | | InsecureRandomness.cs:29:13:29:18 | [post] access to local variable result : StringBuilder [element] : String | semmle.label | [post] access to local variable result : StringBuilder [element] : String |
| InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | semmle.label | call to method GetString : String | | InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | semmle.label | call to method GetString : String |
| InsecureRandomness.cs:29:57:29:60 | access to local variable data : Byte[] [element] : Int32 | semmle.label | access to local variable data : Byte[] [element] : Int32 | | InsecureRandomness.cs:29:57:29:60 | access to local variable data : Byte[] [element] : Byte | semmle.label | access to local variable data : Byte[] [element] : Byte |
| InsecureRandomness.cs:31:16:31:21 | access to local variable result : StringBuilder [element] : String | semmle.label | access to local variable result : StringBuilder [element] : String | | InsecureRandomness.cs:31:16:31:21 | access to local variable result : StringBuilder [element] : String | semmle.label | access to local variable result : StringBuilder [element] : String |
| InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | semmle.label | call to method ToString : String | | InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | semmle.label | call to method ToString : String |
| InsecureRandomness.cs:60:31:60:39 | call to method Next : Int32 | semmle.label | call to method Next : Int32 | | InsecureRandomness.cs:60:31:60:39 | call to method Next : Int32 | semmle.label | call to method Next : Int32 |

View File

@@ -139,7 +139,7 @@ Parameterized modules
===================== =====================
Parameterized modules are QL's approach to generic programming. Parameterized modules are QL's approach to generic programming.
Similar to explicit modules, parameterized modules are defined within other modules using the keywork ``module``. Similar to explicit modules, parameterized modules are defined within other modules using the keyword ``module``.
In addition to the module name, parameterized modules declare one or more parameters between the name and the module body. In addition to the module name, parameterized modules declare one or more parameters between the name and the module body.
For example, consider the module ``M``, which takes two predicate parameters and defines a new predicate For example, consider the module ``M``, which takes two predicate parameters and defines a new predicate

View File

@@ -1135,8 +1135,8 @@ module Impl<FullStateConfigSig Config> {
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow
); );
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap); predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t);
bindingset[typ, contentType] bindingset[typ, contentType]
predicate typecheckStore(Typ typ, DataFlowType contentType); predicate typecheckStore(Typ typ, DataFlowType contentType);
@@ -1199,17 +1199,21 @@ module Impl<FullStateConfigSig Config> {
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
ApOption argAp, Typ t, Ap ap, ApApprox apa ApOption argAp, Typ t, Ap ap, ApApprox apa
) { ) {
fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t, ap, apa) and fwdFlow1(node, state, cc, summaryCtx, argT, argAp, _, t, ap, apa)
PrevStage::revFlow(node, state, apa) and
filter(node, state, t, ap)
} }
pragma[inline] private predicate fwdFlow1(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
ApOption argAp, Typ t, Ap ap ApOption argAp, Typ t0, Typ t, Ap ap, ApApprox apa
) { ) {
fwdFlow(node, state, cc, summaryCtx, argT, argAp, t, ap, _) fwdFlow0(node, state, cc, summaryCtx, argT, argAp, t0, ap, apa) and
PrevStage::revFlow(node, state, apa) and
filter(node, state, t0, ap, t)
}
pragma[nomagic]
private predicate typeStrengthen(Typ t0, Ap ap, Typ t) {
fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t
} }
pragma[assume_small_delta] pragma[assume_small_delta]
@@ -1339,6 +1343,11 @@ module Impl<FullStateConfigSig Config> {
private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) { private predicate fwdFlowConsCand(Typ t2, Ap cons, Content c, Typ t1, Ap tail) {
fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and fwdFlowStore(_, t1, tail, c, t2, _, _, _, _, _, _) and
cons = apCons(c, t1, tail) cons = apCons(c, t1, tail)
or
exists(Typ t0 |
typeStrengthen(t0, cons, t2) and
fwdFlowConsCand(t0, cons, c, t1, tail)
)
} }
pragma[nomagic] pragma[nomagic]
@@ -1359,7 +1368,7 @@ module Impl<FullStateConfigSig Config> {
ParamNodeOption summaryCtx, TypOption argT, ApOption argAp ParamNodeOption summaryCtx, TypOption argT, ApOption argAp
) { ) {
exists(ApHeadContent apc | exists(ApHeadContent apc |
fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap) and fwdFlow(node1, state, cc, summaryCtx, argT, argAp, t, ap, _) and
apc = getHeadContent(ap) and apc = getHeadContent(ap) and
readStepCand0(node1, apc, c, node2) readStepCand0(node1, apc, c, node2)
) )
@@ -1520,14 +1529,14 @@ module Impl<FullStateConfigSig Config> {
NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap
) { ) {
revFlow0(node, state, returnCtx, returnAp, ap) and revFlow0(node, state, returnCtx, returnAp, ap) and
fwdFlow(node, state, _, _, _, _, _, ap) fwdFlow(node, state, _, _, _, _, _, ap, _)
} }
pragma[nomagic] pragma[nomagic]
private predicate revFlow0( private predicate revFlow0(
NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap NodeEx node, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap
) { ) {
fwdFlow(node, state, _, _, _, _, _, ap) and fwdFlow(node, state, _, _, _, _, _, ap, _) and
sinkNode(node, state) and sinkNode(node, state) and
( (
if hasSinkCallCtx() if hasSinkCallCtx()
@@ -1780,13 +1789,13 @@ module Impl<FullStateConfigSig Config> {
boolean fwd, int nodes, int fields, int conscand, int states, int tuples boolean fwd, int nodes, int fields, int conscand, int states, int tuples
) { ) {
fwd = true and fwd = true and
nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _)) and nodes = count(NodeEx node | fwdFlow(node, _, _, _, _, _, _, _, _)) and
fields = count(Content f0 | fwdConsCand(f0, _, _)) and fields = count(Content f0 | fwdConsCand(f0, _, _)) and
conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and conscand = count(Content f0, Typ t, Ap ap | fwdConsCand(f0, t, ap)) and
states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _)) and states = count(FlowState state | fwdFlow(_, state, _, _, _, _, _, _, _)) and
tuples = tuples =
count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, count(NodeEx n, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT,
ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap)) ApOption argAp, Typ t, Ap ap | fwdFlow(n, state, cc, summaryCtx, argT, argAp, t, ap, _))
or or
fwd = false and fwd = false and
nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and nodes = count(NodeEx node | revFlow(node, _, _, _, _)) and
@@ -1963,10 +1972,10 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
PrevStage::revFlowState(state) and PrevStage::revFlowState(state) and
exists(t) and t0 = t and
exists(ap) and exists(ap) and
not stateBarrier(node, state) and not stateBarrier(node, state) and
( (
@@ -2197,8 +2206,8 @@ module Impl<FullStateConfigSig Config> {
import BooleanCallContext import BooleanCallContext
predicate localStep( predicate localStep(
NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t,
DataFlowType t, LocalCc lcc LocalCc lcc
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and
exists(lcc) exists(lcc)
@@ -2218,10 +2227,16 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
exists(state) and exists(state) and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and // We can get away with not using type strengthening here, since we aren't
// going to use the tracked types in the construction of Stage 4 access
// paths. For Stage 4 and onwards, the tracked types must be consistent as
// the cons candidates including types are used to construct subsequent
// access path approximations.
t0 = t and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t0) else any()) and
( (
notExpectsContent(node) notExpectsContent(node)
or or
@@ -2241,6 +2256,16 @@ module Impl<FullStateConfigSig Config> {
import MkStage<Stage2>::Stage<Stage3Param> import MkStage<Stage2>::Stage<Stage3Param>
} }
bindingset[node, t0]
private predicate strengthenType(NodeEx node, DataFlowType t0, DataFlowType t) {
if castingNodeEx(node)
then
exists(DataFlowType nt | nt = node.getDataFlowType() |
if typeStrongerThan(nt, t0) then t = nt else (compatibleTypes(nt, t0) and t = t0)
)
else t = t0
}
private module Stage4Param implements MkStage<Stage3>::StageParam { private module Stage4Param implements MkStage<Stage3>::StageParam {
private module PrevStage = Stage3; private module PrevStage = Stage3;
@@ -2274,8 +2299,8 @@ module Impl<FullStateConfigSig Config> {
pragma[nomagic] pragma[nomagic]
predicate localStep( predicate localStep(
NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t,
DataFlowType t, LocalCc lcc LocalCc lcc
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and localFlowBigStep(node1, state1, node2, state2, preservesValue, t, _) and
PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and
@@ -2333,11 +2358,11 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
exists(state) and exists(state) and
not clear(node, ap) and not clear(node, ap) and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and strengthenType(node, t0, t) and
( (
notExpectsContent(node) notExpectsContent(node)
or or
@@ -2365,7 +2390,7 @@ module Impl<FullStateConfigSig Config> {
exists(AccessPathFront apf | exists(AccessPathFront apf |
Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and Stage4::revFlow(node, state, TReturnCtxMaybeFlowThrough(_), _, apf) and
Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _, Stage4::fwdFlow(node, state, any(Stage4::CcCall ccc), _, _, TAccessPathFrontSome(argApf), _,
apf) apf, _)
) )
} }
@@ -2579,8 +2604,8 @@ module Impl<FullStateConfigSig Config> {
import LocalCallContext import LocalCallContext
predicate localStep( predicate localStep(
NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, boolean preservesValue, Typ t,
DataFlowType t, LocalCc lcc LocalCc lcc
) { ) {
localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and localFlowBigStep(node1, state1, node2, state2, preservesValue, t, lcc) and
PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and PrevStage::revFlow(node1, pragma[only_bind_into](state1), _) and
@@ -2609,9 +2634,9 @@ module Impl<FullStateConfigSig Config> {
) )
} }
bindingset[node, state, t, ap] bindingset[node, state, t0, ap]
predicate filter(NodeEx node, FlowState state, Typ t, Ap ap) { predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any()) and strengthenType(node, t0, t) and
exists(state) and exists(state) and
exists(ap) exists(ap)
} }
@@ -2632,7 +2657,7 @@ module Impl<FullStateConfigSig Config> {
Stage5::parameterMayFlowThrough(p, _) and Stage5::parameterMayFlowThrough(p, _) and
Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and Stage5::revFlow(n, state, TReturnCtxMaybeFlowThrough(_), _, apa0) and
Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _, Stage5::fwdFlow(n, state, any(CallContextCall ccc), TParamNodeSome(p.asNode()), _,
TAccessPathApproxSome(apa), _, apa0) TAccessPathApproxSome(apa), _, apa0, _)
) )
} }
@@ -2649,7 +2674,7 @@ module Impl<FullStateConfigSig Config> {
TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) { TSummaryCtxSome(ParamNodeEx p, FlowState state, DataFlowType t, AccessPath ap) {
exists(AccessPathApprox apa | ap.getApprox() = apa | exists(AccessPathApprox apa | ap.getApprox() = apa |
Stage5::parameterMayFlowThrough(p, apa) and Stage5::parameterMayFlowThrough(p, apa) and
Stage5::fwdFlow(p, state, _, _, _, _, t, apa) and Stage5::fwdFlow(p, state, _, _, Option<DataFlowType>::some(t), _, _, apa, _) and
Stage5::revFlow(p, state, _) Stage5::revFlow(p, state, _)
) )
} }
@@ -2820,9 +2845,7 @@ module Impl<FullStateConfigSig Config> {
ap = TAccessPathNil() ap = TAccessPathNil()
or or
// ... or a step from an existing PathNode to another node. // ... or a step from an existing PathNode to another node.
pathStep(_, node, state, cc, sc, t, ap) and pathStep(_, node, state, cc, sc, t, ap)
Stage5::revFlow(node, state, ap.getApprox()) and
(if castingNodeEx(node) then compatibleTypes(node.getDataFlowType(), t) else any())
} or } or
TPathNodeSink(NodeEx node, FlowState state) { TPathNodeSink(NodeEx node, FlowState state) {
exists(PathNodeMid sink | exists(PathNodeMid sink |
@@ -3340,13 +3363,24 @@ module Impl<FullStateConfigSig Config> {
ap = mid.getAp() ap = mid.getAp()
} }
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t,
AccessPath ap
) {
exists(DataFlowType t0 |
pathStep0(mid, node, state, cc, sc, t0, ap) and
Stage5::revFlow(node, state, ap.getApprox()) and
strengthenType(node, t0, t)
)
}
/** /**
* Holds if data may flow from `mid` to `node`. The last step in or out of * Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`. * a callable is recorded by `cc`.
*/ */
pragma[assume_small_delta] pragma[assume_small_delta]
pragma[nomagic] pragma[nomagic]
private predicate pathStep( private predicate pathStep0(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t,
AccessPath ap AccessPath ap
) { ) {
@@ -3964,7 +3998,7 @@ module Impl<FullStateConfigSig Config> {
ap = TPartialNil() and ap = TPartialNil() and
exists(explorationLimit()) exists(explorationLimit())
or or
partialPathNodeMk0(node, state, cc, sc1, sc2, sc3, sc4, t, ap) and partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and
distSrc(node.getEnclosingCallable()) <= explorationLimit() distSrc(node.getEnclosingCallable()) <= explorationLimit()
} or } or
TPartialPathNodeRev( TPartialPathNodeRev(
@@ -3990,11 +4024,20 @@ module Impl<FullStateConfigSig Config> {
} }
pragma[nomagic] pragma[nomagic]
private predicate partialPathNodeMk0( private predicate partialPathStep(
NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1,
TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap
) { ) {
partialPathStep(_, node, state, cc, sc1, sc2, sc3, sc4, t, ap) and partialPathStep1(mid, node, state, cc, sc1, sc2, sc3, sc4, _, t, ap)
}
pragma[nomagic]
private predicate partialPathStep1(
PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1,
TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t0, DataFlowType t,
PartialAccessPath ap
) {
partialPathStep0(mid, node, state, cc, sc1, sc2, sc3, sc4, t0, ap) and
not fullBarrier(node) and not fullBarrier(node) and
not stateBarrier(node, state) and not stateBarrier(node, state) and
not clearsContentEx(node, ap.getHead()) and not clearsContentEx(node, ap.getHead()) and
@@ -4002,9 +4045,14 @@ module Impl<FullStateConfigSig Config> {
notExpectsContent(node) or notExpectsContent(node) or
expectsContentEx(node, ap.getHead()) expectsContentEx(node, ap.getHead())
) and ) and
if node.asNode() instanceof CastingNode strengthenType(node, t0, t)
then compatibleTypes(node.getDataFlowType(), t) }
else any()
pragma[nomagic]
private predicate partialPathTypeStrengthen(
DataFlowType t0, PartialAccessPath ap, DataFlowType t
) {
partialPathStep1(_, _, _, _, _, _, _, _, t0, t, ap) and t0 != t
} }
/** /**
@@ -4183,7 +4231,8 @@ module Impl<FullStateConfigSig Config> {
} }
} }
private predicate partialPathStep( pragma[nomagic]
private predicate partialPathStep0(
PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1,
TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap
) { ) {
@@ -4309,6 +4358,11 @@ module Impl<FullStateConfigSig Config> {
DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2 DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2
) { ) {
partialPathStoreStep(_, t1, ap1, c, _, t2, ap2) partialPathStoreStep(_, t1, ap1, c, _, t2, ap2)
or
exists(DataFlowType t0 |
partialPathTypeStrengthen(t0, ap2, t2) and
apConsFwd(t1, ap1, c, t0, ap2)
)
} }
pragma[nomagic] pragma[nomagic]

View File

@@ -200,6 +200,8 @@ predicate expectsContent(Node n, ContentSet c) {
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n, c) FlowSummaryImpl::Private::Steps::summaryExpectsContent(n, c)
} }
predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() }
/** Gets the type of `n` used for type pruning. */ /** Gets the type of `n` used for type pruning. */
DataFlowType getNodeType(Node n) { result = TTodoDataFlowType() and exists(n) } DataFlowType getNodeType(Node n) { result = TTodoDataFlowType() and exists(n) }

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -2,14 +2,10 @@ import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
import experimental.frameworks.CleverGo import experimental.frameworks.CleverGo
class HttpHeaderWriteTest extends InlineExpectationsTest { module HttpHeaderWriteTest implements TestSig {
HttpHeaderWriteTest() { this = "HttpHeaderWriteTest" } string getARelevantTag() { result = ["headerKeyNode", "headerValNode", "headerKey", "headerVal"] }
override string getARelevantTag() { predicate hasActualResult(Location location, string element, string tag, string value) {
result = ["headerKeyNode", "headerValNode", "headerKey", "headerVal"]
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
// Dynamic key-value header: // Dynamic key-value header:
exists(Http::HeaderWrite hw | exists(Http::HeaderWrite hw |
hw.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), hw.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
@@ -56,3 +52,5 @@ class HttpHeaderWriteTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<HttpHeaderWriteTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -2,12 +2,10 @@ import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
import experimental.frameworks.CleverGo import experimental.frameworks.CleverGo
class HttpRedirectTest extends InlineExpectationsTest { module HttpRedirectTest implements TestSig {
HttpRedirectTest() { this = "HttpRedirectTest" } string getARelevantTag() { result = "redirectUrl" }
override string getARelevantTag() { result = "redirectUrl" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "redirectUrl" and tag = "redirectUrl" and
exists(Http::Redirect rd | exists(Http::Redirect rd |
rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
@@ -17,3 +15,5 @@ class HttpRedirectTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<HttpRedirectTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -2,12 +2,10 @@ import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
import experimental.frameworks.CleverGo import experimental.frameworks.CleverGo
class HttpResponseBodyTest extends InlineExpectationsTest { module HttpResponseBodyTest implements TestSig {
HttpResponseBodyTest() { this = "HttpResponseBodyTest" } string getARelevantTag() { result = ["contentType", "responseBody"] }
override string getARelevantTag() { result = ["contentType", "responseBody"] } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Http::ResponseBody rd | exists(Http::ResponseBody rd |
rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and
@@ -23,3 +21,5 @@ class HttpResponseBodyTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<HttpResponseBodyTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -14,12 +14,10 @@ class Configuration extends TaintTracking::Configuration {
} }
} }
class TaintTrackingTest extends InlineExpectationsTest { module TaintTrackingTest implements TestSig {
TaintTrackingTest() { this = "TaintTrackingTest" } string getARelevantTag() { result = "taintSink" }
override string getARelevantTag() { result = "taintSink" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "taintSink" and tag = "taintSink" and
exists(DataFlow::Node sink | any(Configuration c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(Configuration c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -29,3 +27,5 @@ class TaintTrackingTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<TaintTrackingTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -2,12 +2,10 @@ import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
import experimental.frameworks.CleverGo import experimental.frameworks.CleverGo
class UntrustedFlowSourceTest extends InlineExpectationsTest { module UntrustedFlowSourceTest implements TestSig {
UntrustedFlowSourceTest() { this = "UntrustedFlowSourceTest" } string getARelevantTag() { result = "untrustedFlowSource" }
override string getARelevantTag() { result = "untrustedFlowSource" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "untrustedFlowSource" and tag = "untrustedFlowSource" and
exists(DataFlow::CallNode sinkCall, DataFlow::ArgumentNode arg | exists(DataFlow::CallNode sinkCall, DataFlow::ArgumentNode arg |
sinkCall.getCalleeName() = "sink" and sinkCall.getCalleeName() = "sink" and
@@ -21,3 +19,5 @@ class UntrustedFlowSourceTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<UntrustedFlowSourceTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -2,14 +2,10 @@ import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
import experimental.frameworks.Fiber import experimental.frameworks.Fiber
class HttpHeaderWriteTest extends InlineExpectationsTest { module HttpHeaderWriteTest implements TestSig {
HttpHeaderWriteTest() { this = "HttpHeaderWriteTest" } string getARelevantTag() { result = ["headerKeyNode", "headerValNode", "headerKey", "headerVal"] }
override string getARelevantTag() { predicate hasActualResult(Location location, string element, string tag, string value) {
result = ["headerKeyNode", "headerValNode", "headerKey", "headerVal"]
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
// Dynamic key-value header: // Dynamic key-value header:
exists(Http::HeaderWrite hw | exists(Http::HeaderWrite hw |
hw.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), hw.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
@@ -56,3 +52,5 @@ class HttpHeaderWriteTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<HttpHeaderWriteTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -2,12 +2,10 @@ import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
import experimental.frameworks.Fiber import experimental.frameworks.Fiber
class HttpRedirectTest extends InlineExpectationsTest { module HttpRedirectTest implements TestSig {
HttpRedirectTest() { this = "HttpRedirectTest" } string getARelevantTag() { result = "redirectUrl" }
override string getARelevantTag() { result = "redirectUrl" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "redirectUrl" and tag = "redirectUrl" and
exists(Http::Redirect rd | exists(Http::Redirect rd |
rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
@@ -17,3 +15,5 @@ class HttpRedirectTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<HttpRedirectTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -2,12 +2,10 @@ import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
import experimental.frameworks.Fiber import experimental.frameworks.Fiber
class HttpResponseBodyTest extends InlineExpectationsTest { module HttpResponseBodyTest implements TestSig {
HttpResponseBodyTest() { this = "HttpResponseBodyTest" } string getARelevantTag() { result = ["contentType", "responseBody"] }
override string getARelevantTag() { result = ["contentType", "responseBody"] } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Http::ResponseBody rd | exists(Http::ResponseBody rd |
rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), rd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and
@@ -23,3 +21,5 @@ class HttpResponseBodyTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<HttpResponseBodyTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -14,12 +14,10 @@ class Configuration extends TaintTracking::Configuration {
} }
} }
class TaintTrackingTest extends InlineExpectationsTest { module TaintTrackingTest implements TestSig {
TaintTrackingTest() { this = "TaintTrackingTest" } string getARelevantTag() { result = "taintSink" }
override string getARelevantTag() { result = "taintSink" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "taintSink" and tag = "taintSink" and
exists(DataFlow::Node sink | any(Configuration c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(Configuration c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -29,3 +27,5 @@ class TaintTrackingTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<TaintTrackingTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -2,12 +2,10 @@ import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
import experimental.frameworks.Fiber import experimental.frameworks.Fiber
class UntrustedFlowSourceTest extends InlineExpectationsTest { module UntrustedFlowSourceTest implements TestSig {
UntrustedFlowSourceTest() { this = "UntrustedFlowSourceTest" } string getARelevantTag() { result = "untrustedFlowSource" }
override string getARelevantTag() { result = "untrustedFlowSource" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "untrustedFlowSource" and tag = "untrustedFlowSource" and
exists(DataFlow::CallNode sinkCall, DataFlow::ArgumentNode arg | exists(DataFlow::CallNode sinkCall, DataFlow::ArgumentNode arg |
sinkCall.getCalleeName() = "sink" and sinkCall.getCalleeName() = "sink" and
@@ -21,3 +19,5 @@ class UntrustedFlowSourceTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<UntrustedFlowSourceTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -1,12 +1,10 @@
import go import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
class FunctionIsVariadicTest extends InlineExpectationsTest { module FunctionIsVariadicTest implements TestSig {
FunctionIsVariadicTest() { this = "Function::IsVariadicTest" } string getARelevantTag() { result = "isVariadic" }
override string getARelevantTag() { result = "isVariadic" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(CallExpr ce | exists(CallExpr ce |
ce.getTarget().isVariadic() and ce.getTarget().isVariadic() and
ce.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), ce.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
@@ -17,3 +15,5 @@ class FunctionIsVariadicTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<FunctionIsVariadicTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -1,12 +1,10 @@
import go import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
class ImplementsComparableTest extends InlineExpectationsTest { module ImplementsComparableTest implements TestSig {
ImplementsComparableTest() { this = "ImplementsComparableTest" } string getARelevantTag() { result = "implementsComparable" }
override string getARelevantTag() { result = "implementsComparable" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
// file = "interface.go" and // file = "interface.go" and
tag = "implementsComparable" and tag = "implementsComparable" and
exists(TypeSpec ts | exists(TypeSpec ts |
@@ -20,3 +18,5 @@ class ImplementsComparableTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<ImplementsComparableTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -1,12 +1,10 @@
import go import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
class SignatureTypeIsVariadicTest extends InlineExpectationsTest { module SignatureTypeIsVariadicTest implements TestSig {
SignatureTypeIsVariadicTest() { this = "SignatureType::IsVariadicTest" } string getARelevantTag() { result = "isVariadic" }
override string getARelevantTag() { result = "isVariadic" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(FuncDef fd | exists(FuncDef fd |
fd.isVariadic() and fd.isVariadic() and
fd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), fd.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
@@ -17,3 +15,5 @@ class SignatureTypeIsVariadicTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<SignatureTypeIsVariadicTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -1,12 +1,10 @@
import go import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
class HttpHandler extends InlineExpectationsTest { module HttpHandler implements TestSig {
HttpHandler() { this = "httphandler" } string getARelevantTag() { result = "handler" }
override string getARelevantTag() { result = "handler" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "handler" and tag = "handler" and
exists(Http::RequestHandler h, DataFlow::Node check | exists(Http::RequestHandler h, DataFlow::Node check |
element = h.toString() and value = check.toString() element = h.toString() and value = check.toString()
@@ -17,3 +15,5 @@ class HttpHandler extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<HttpHandler>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -1,12 +1,10 @@
import go import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
class LoggerTest extends InlineExpectationsTest { module LoggerTest implements TestSig {
LoggerTest() { this = "LoggerTest" } string getARelevantTag() { result = "logger" }
override string getARelevantTag() { result = "logger" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(LoggerCall log | exists(LoggerCall log |
log.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), log.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and
@@ -16,3 +14,5 @@ class LoggerTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<LoggerTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -13,12 +13,10 @@ class DataConfiguration extends DataFlow::Configuration {
} }
} }
class DataFlowTest extends InlineExpectationsTest { module DataFlowTest implements TestSig {
DataFlowTest() { this = "DataFlowTest" } string getARelevantTag() { result = "dataflow" }
override string getARelevantTag() { result = "dataflow" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "dataflow" and tag = "dataflow" and
exists(DataFlow::Node sink | any(DataConfiguration c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(DataConfiguration c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -41,12 +39,10 @@ class TaintConfiguration extends TaintTracking::Configuration {
} }
} }
class TaintFlowTest extends InlineExpectationsTest { module TaintFlowTest implements TestSig {
TaintFlowTest() { this = "TaintFlowTest" } string getARelevantTag() { result = "taintflow" }
override string getARelevantTag() { result = "taintflow" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "taintflow" and tag = "taintflow" and
exists(DataFlow::Node sink | any(TaintConfiguration c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(TaintConfiguration c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -56,3 +52,5 @@ class TaintFlowTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<MergeTests<DataFlowTest, TaintFlowTest>>

View File

@@ -1,2 +1,3 @@
failures failures
invalidModelRow invalidModelRow
testFailures

View File

@@ -15,12 +15,10 @@ class DataConfiguration extends DataFlow::Configuration {
} }
} }
class DataFlowTest extends InlineExpectationsTest { module DataFlowTest implements TestSig {
DataFlowTest() { this = "DataFlowTest" } string getARelevantTag() { result = "dataflow" }
override string getARelevantTag() { result = "dataflow" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "dataflow" and tag = "dataflow" and
exists(DataFlow::Node sink | any(DataConfiguration c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(DataConfiguration c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -43,12 +41,10 @@ class TaintConfiguration extends TaintTracking::Configuration {
} }
} }
class TaintFlowTest extends InlineExpectationsTest { module TaintFlowTest implements TestSig {
TaintFlowTest() { this = "TaintFlowTest" } string getARelevantTag() { result = "taintflow" }
override string getARelevantTag() { result = "taintflow" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "taintflow" and tag = "taintflow" and
exists(DataFlow::Node sink | any(TaintConfiguration c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(TaintConfiguration c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -58,3 +54,5 @@ class TaintFlowTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<MergeTests<DataFlowTest, TaintFlowTest>>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -23,12 +23,10 @@ class TestConfig extends DataFlow::Configuration {
} }
} }
class DataFlowTest extends InlineExpectationsTest { module DataFlowTest implements TestSig {
DataFlowTest() { this = "DataFlowTest" } string getARelevantTag() { result = "dataflow" }
override string getARelevantTag() { result = "dataflow" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "dataflow" and tag = "dataflow" and
exists(DataFlow::Node sink | any(TestConfig c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(TestConfig c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -38,3 +36,5 @@ class DataFlowTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<DataFlowTest>

View File

@@ -13,12 +13,10 @@ class TestConfig extends TaintTracking::Configuration {
} }
} }
class DataFlowTest extends InlineExpectationsTest { module DataFlowTest implements TestSig {
DataFlowTest() { this = "DataFlowTest" } string getARelevantTag() { result = "dataflow" }
override string getARelevantTag() { result = "dataflow" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "dataflow" and tag = "dataflow" and
exists(DataFlow::Node sink | any(TestConfig c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(TestConfig c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -28,3 +26,5 @@ class DataFlowTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<DataFlowTest>

View File

@@ -21,12 +21,10 @@ class TestConfig extends DataFlow::Configuration {
} }
} }
class PromotedFieldsTest extends InlineExpectationsTest { module PromotedFieldsTest implements TestSig {
PromotedFieldsTest() { this = "PromotedFieldsTest" } string getARelevantTag() { result = "promotedfields" }
override string getARelevantTag() { result = "promotedfields" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(TestConfig config, DataFlow::PathNode sink | exists(TestConfig config, DataFlow::PathNode sink |
config.hasFlowPath(_, sink) and config.hasFlowPath(_, sink) and
sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
@@ -37,3 +35,5 @@ class PromotedFieldsTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<PromotedFieldsTest>

View File

@@ -21,12 +21,10 @@ class TestConfig extends DataFlow::Configuration {
} }
} }
class PromotedMethodsTest extends InlineExpectationsTest { module PromotedMethodsTest implements TestSig {
PromotedMethodsTest() { this = "PromotedMethodsTest" } string getARelevantTag() { result = "promotedmethods" }
override string getARelevantTag() { result = "promotedmethods" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(TestConfig config, DataFlow::Node source, DataFlow::Node sink | exists(TestConfig config, DataFlow::Node source, DataFlow::Node sink |
config.hasFlow(source, sink) config.hasFlow(source, sink)
| |
@@ -38,3 +36,5 @@ class PromotedMethodsTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<PromotedMethodsTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -13,12 +13,10 @@ class Configuration extends DataFlow::Configuration {
} }
} }
class DataFlowTest extends InlineExpectationsTest { module DataFlowTest implements TestSig {
DataFlowTest() { this = "DataFlowTest" } string getARelevantTag() { result = "dataflow" }
override string getARelevantTag() { result = "dataflow" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "dataflow" and tag = "dataflow" and
exists(DataFlow::Node sink | any(Configuration c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(Configuration c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -28,3 +26,5 @@ class DataFlowTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<DataFlowTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -13,12 +13,10 @@ class DataConfiguration extends DataFlow::Configuration {
} }
} }
class DataFlowTest extends InlineExpectationsTest { module DataFlowTest implements TestSig {
DataFlowTest() { this = "DataFlowTest" } string getARelevantTag() { result = "dataflow" }
override string getARelevantTag() { result = "dataflow" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "dataflow" and tag = "dataflow" and
exists(DataFlow::Node sink | any(DataConfiguration c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(DataConfiguration c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -41,12 +39,10 @@ class TaintConfiguration extends TaintTracking::Configuration {
} }
} }
class TaintFlowTest extends InlineExpectationsTest { module TaintFlowTest implements TestSig {
TaintFlowTest() { this = "TaintFlowTest" } string getARelevantTag() { result = "taintflow" }
override string getARelevantTag() { result = "taintflow" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "taintflow" and tag = "taintflow" and
exists(DataFlow::Node sink | any(TaintConfiguration c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(TaintConfiguration c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -56,3 +52,5 @@ class TaintFlowTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<MergeTests<DataFlowTest, TaintFlowTest>>

View File

@@ -1,2 +1,3 @@
failures failures
invalidModelRow invalidModelRow
testFailures

View File

@@ -43,12 +43,10 @@ class DataConfiguration extends DataFlow::Configuration {
} }
} }
class DataFlowTest extends InlineExpectationsTest { module DataFlowTest implements TestSig {
DataFlowTest() { this = "DataFlowTest" } string getARelevantTag() { result = "dataflow" }
override string getARelevantTag() { result = "dataflow" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "dataflow" and tag = "dataflow" and
exists(DataFlow::Node sink | any(DataConfiguration c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(DataConfiguration c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -71,12 +69,10 @@ class TaintConfiguration extends TaintTracking::Configuration {
} }
} }
class TaintFlowTest extends InlineExpectationsTest { module TaintFlowTest implements TestSig {
TaintFlowTest() { this = "TaintFlowTest" } string getARelevantTag() { result = "taintflow" }
override string getARelevantTag() { result = "taintflow" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "taintflow" and tag = "taintflow" and
exists(DataFlow::Node sink | any(TaintConfiguration c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(TaintConfiguration c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -86,9 +82,5 @@ class TaintFlowTest extends InlineExpectationsTest {
) )
} }
} }
// from TaintConfiguration cfg, DataFlow::PartialPathNode source, DataFlow::PartialPathNode sink
// where import MakeTest<MergeTests<DataFlowTest, TaintFlowTest>>
// cfg.hasPartialFlow(source, sink, _)
// and
// source.getNode().hasLocationInfo(_, 22, _, _, _)
// select sink, source, sink, "Partial flow from unsanitized user data"

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -2,12 +2,10 @@ import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
import semmle.go.security.SqlInjection import semmle.go.security.SqlInjection
class SqlInjectionTest extends InlineExpectationsTest { module SqlInjectionTest implements TestSig {
SqlInjectionTest() { this = "SqlInjectionTest" } string getARelevantTag() { result = "sqlinjection" }
override string getARelevantTag() { result = "sqlinjection" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "sqlinjection" and tag = "sqlinjection" and
exists(DataFlow::Node sink | any(SqlInjection::Configuration c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(SqlInjection::Configuration c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -17,3 +15,5 @@ class SqlInjectionTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<SqlInjectionTest>

View File

@@ -16,12 +16,10 @@ class Configuration extends TaintTracking::Configuration {
} }
} }
class TaintFlowTest extends InlineExpectationsTest { module TaintFlowTest implements TestSig {
TaintFlowTest() { this = "TaintFlowTest" } string getARelevantTag() { result = "taintflow" }
override string getARelevantTag() { result = "taintflow" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "taintflow" and tag = "taintflow" and
exists(DataFlow::Node sink | any(Configuration c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(Configuration c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -31,3 +29,5 @@ class TaintFlowTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<TaintFlowTest>

View File

@@ -2,12 +2,10 @@ import go
import semmle.go.frameworks.GoKit import semmle.go.frameworks.GoKit
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
class UntrustedFlowSourceTest extends InlineExpectationsTest { module UntrustedFlowSourceTest implements TestSig {
UntrustedFlowSourceTest() { this = "untrustedflowsourcetest" } string getARelevantTag() { result = "source" }
override string getARelevantTag() { result = "source" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(UntrustedFlowSource source | exists(UntrustedFlowSource source |
source source
.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), .hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
@@ -18,3 +16,5 @@ class UntrustedFlowSourceTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<UntrustedFlowSourceTest>

View File

@@ -21,12 +21,10 @@ class TestConfig extends TaintTracking::Configuration {
} }
} }
class K8sIoApiCoreV1Test extends InlineExpectationsTest { module K8sIoApiCoreV1Test implements TestSig {
K8sIoApiCoreV1Test() { this = "K8sIoApiCoreV1Test" } string getARelevantTag() { result = "KsIoApiCoreV" }
override string getARelevantTag() { result = "KsIoApiCoreV" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(TestConfig config, DataFlow::PathNode sink | exists(TestConfig config, DataFlow::PathNode sink |
config.hasFlowPath(_, sink) and config.hasFlowPath(_, sink) and
sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
@@ -37,3 +35,5 @@ class K8sIoApiCoreV1Test extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<K8sIoApiCoreV1Test>

View File

@@ -21,12 +21,10 @@ class TestConfig extends TaintTracking::Configuration {
} }
} }
class K8sIoApimachineryPkgRuntimeTest extends InlineExpectationsTest { module K8sIoApimachineryPkgRuntimeTest implements TestSig {
K8sIoApimachineryPkgRuntimeTest() { this = "KsIoApimachineryPkgRuntimeTest" } string getARelevantTag() { result = "KsIoApimachineryPkgRuntime" }
override string getARelevantTag() { result = "KsIoApimachineryPkgRuntime" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(TestConfig config, DataFlow::PathNode sink | exists(TestConfig config, DataFlow::PathNode sink |
config.hasFlowPath(_, sink) and config.hasFlowPath(_, sink) and
sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
@@ -37,3 +35,5 @@ class K8sIoApimachineryPkgRuntimeTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<K8sIoApimachineryPkgRuntimeTest>

View File

@@ -1,12 +1,10 @@
import go import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
class K8sIoApimachineryPkgRuntimeTest extends InlineExpectationsTest { module K8sIoApimachineryPkgRuntimeTest implements TestSig {
K8sIoApimachineryPkgRuntimeTest() { this = "KsIoClientGoTest" } string getARelevantTag() { result = "KsIoClientGo" }
override string getARelevantTag() { result = "KsIoClientGo" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(K8sIoClientGo::SecretInterfaceSource source | exists(K8sIoClientGo::SecretInterfaceSource source |
source source
.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), .hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
@@ -17,3 +15,5 @@ class K8sIoApimachineryPkgRuntimeTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<K8sIoApimachineryPkgRuntimeTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -1,12 +1,10 @@
import go import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
class NoSqlQueryTest extends InlineExpectationsTest { module NoSqlQueryTest implements TestSig {
NoSqlQueryTest() { this = "NoSQLQueryTest" } string getARelevantTag() { result = "nosqlquery" }
override string getARelevantTag() { result = "nosqlquery" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(NoSql::Query q | exists(NoSql::Query q |
q.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), q.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and
@@ -16,3 +14,5 @@ class NoSqlQueryTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<NoSqlQueryTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -15,12 +15,10 @@ class TestConfig extends TaintTracking::Configuration {
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
} }
class MissingDataFlowTest extends InlineExpectationsTest { module MissingDataFlowTest implements TestSig {
MissingDataFlowTest() { this = "MissingDataFlow" } string getARelevantTag() { result = "noflow" }
override string getARelevantTag() { result = "noflow" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "noflow" and tag = "noflow" and
value = "" and value = "" and
exists(Sink sink | exists(Sink sink |
@@ -32,12 +30,10 @@ class MissingDataFlowTest extends InlineExpectationsTest {
} }
} }
class HttpResponseBodyTest extends InlineExpectationsTest { module HttpResponseBodyTest implements TestSig {
HttpResponseBodyTest() { this = "HttpResponseBodyTest" } string getARelevantTag() { result = "responsebody" }
override string getARelevantTag() { result = "responsebody" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "responsebody" and tag = "responsebody" and
exists(Http::ResponseBody rb | exists(Http::ResponseBody rb |
rb.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), rb.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
@@ -47,3 +43,5 @@ class HttpResponseBodyTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<MergeTests<MissingDataFlowTest, HttpResponseBodyTest>>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -1,12 +1,10 @@
import go import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
class FileSystemAccessTest extends InlineExpectationsTest { module FileSystemAccessTest implements TestSig {
FileSystemAccessTest() { this = "FileSystemAccess" } string getARelevantTag() { result = "fsaccess" }
override string getARelevantTag() { result = "fsaccess" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(FileSystemAccess f | exists(FileSystemAccess f |
f.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), f.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and
@@ -16,3 +14,5 @@ class FileSystemAccessTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<FileSystemAccessTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -13,12 +13,10 @@ class TestConfig extends TaintTracking::Configuration {
} }
} }
class ZapTest extends InlineExpectationsTest { module ZapTest implements TestSig {
ZapTest() { this = "ZapTest" } string getARelevantTag() { result = "zap" }
override string getARelevantTag() { result = "zap" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "zap" and tag = "zap" and
exists(DataFlow::Node sink | any(TestConfig c).hasFlow(_, sink) | exists(DataFlow::Node sink | any(TestConfig c).hasFlow(_, sink) |
element = sink.toString() and element = sink.toString() and
@@ -28,3 +26,5 @@ class ZapTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<ZapTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -2,12 +2,10 @@ import go
import TestUtilities.InlineExpectationsTest import TestUtilities.InlineExpectationsTest
import semmle.go.security.IncorrectIntegerConversionLib import semmle.go.security.IncorrectIntegerConversionLib
class TestIncorrectIntegerConversion extends InlineExpectationsTest { module TestIncorrectIntegerConversion implements TestSig {
TestIncorrectIntegerConversion() { this = "TestIncorrectIntegerConversion" } string getARelevantTag() { result = "hasValueFlow" }
override string getARelevantTag() { result = "hasValueFlow" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "hasValueFlow" and tag = "hasValueFlow" and
exists(DataFlow::Node sink, DataFlow::Node sinkConverted | exists(DataFlow::Node sink, DataFlow::Node sinkConverted |
any(ConversionWithoutBoundsCheckConfig config).hasFlowTo(sink) and any(ConversionWithoutBoundsCheckConfig config).hasFlowTo(sink) and
@@ -21,3 +19,5 @@ class TestIncorrectIntegerConversion extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<TestIncorrectIntegerConversion>

View File

@@ -22,7 +22,7 @@ com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17
com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551
com.google.common.flogger,29,,,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,, com.google.common.flogger,29,,,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,,
com.google.common.io,8,,73,,1,,,,,,,,,,,,,,7,,,,,,,,,,,,,,,,,,,72,1 com.google.common.io,8,,73,,1,,,,,,,,,,,,,,7,,,,,,,,,,,,,,,,,,,72,1
com.google.gson,,,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25,14 com.google.gson,,,44,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30,14
com.hubspot.jinjava,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,, com.hubspot.jinjava,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,
com.jcraft.jsch,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,1, com.jcraft.jsch,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,1,
com.mitchellbosecke.pebble,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,, com.mitchellbosecke.pebble,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,
@@ -58,7 +58,7 @@ java.io,49,,45,,22,,,,,,,,,,,,,,27,,,,,,,,,,,,,,,,,,,43,2
java.lang,18,,92,,,,,,,,,,,,,8,,,5,,,4,,,1,,,,,,,,,,,,,56,36 java.lang,18,,92,,,,,,,,,,,,,8,,,5,,,4,,,1,,,,,,,,,,,,,56,36
java.net,13,3,20,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,3,20, java.net,13,3,20,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,3,20,
java.nio,47,,35,,3,,,,,,,,,,,,,,44,,,,,,,,,,,,,,,,,,,35, java.nio,47,,35,,3,,,,,,,,,,,,,,44,,,,,,,,,,,,,,,,,,,35,
java.sql,13,,3,,,,,,,,,,,,,,,,,,,,,,,,,4,,9,,,,,,,,2,1 java.sql,13,,2,,,,,,,,,,,,,,,,,,,,,,,,,4,,9,,,,,,,,2,
java.util,44,,484,,,,,,,,,,,,,34,,,,,,,5,2,,1,2,,,,,,,,,,,44,440 java.util,44,,484,,,,,,,,,,,,,34,,,,,,,5,2,,1,2,,,,,,,,,,,44,440
javafx.scene.web,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, javafx.scene.web,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,
javax.faces.context,2,7,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,, javax.faces.context,2,7,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,
1 package sink source summary sink:bean-validation sink:file-content-store sink:fragment-injection sink:groovy-injection sink:hostname-verification sink:html-injection sink:information-leak sink:intent-redirection sink:jexl-injection sink:jndi-injection sink:js-injection sink:ldap-injection sink:log-injection sink:mvel-injection sink:ognl-injection sink:path-injection sink:pending-intents sink:regex-use sink:regex-use[-1] sink:regex-use[0] sink:regex-use[] sink:regex-use[f-1] sink:regex-use[f1] sink:regex-use[f] sink:request-forgery sink:response-splitting sink:sql-injection sink:template-injection sink:url-redirection sink:xpath-injection sink:xslt-injection source:android-external-storage-dir source:contentprovider source:remote summary:taint summary:value
22 com.google.common.collect 553 2 551
23 com.google.common.flogger 29 29
24 com.google.common.io 8 73 1 7 72 1
25 com.google.gson 39 44 25 30 14
26 com.hubspot.jinjava 2 2
27 com.jcraft.jsch 1 1 1 1
28 com.mitchellbosecke.pebble 2 2
58 java.lang 18 92 8 5 4 1 56 36
59 java.net 13 3 20 13 3 20
60 java.nio 47 35 3 44 35
61 java.sql 13 3 2 4 9 2 1
62 java.util 44 484 34 5 2 1 2 44 440
63 javafx.scene.web 1 1
64 javax.faces.context 2 7 2 7

View File

@@ -18,10 +18,10 @@ Java framework & library support
`Google Guava <https://guava.dev/>`_,``com.google.common.*``,,730,41,7,,,,, `Google Guava <https://guava.dev/>`_,``com.google.common.*``,,730,41,7,,,,,
JBoss Logging,``org.jboss.logging``,,,324,,,,,, JBoss Logging,``org.jboss.logging``,,,324,,,,,,
`JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,, `JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,,
Java Standard Library,``java.*``,3,683,184,76,,9,,,17 Java Standard Library,``java.*``,3,682,184,76,,9,,,17
Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,2,4,,1,1,2 Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,2,4,,1,1,2
Kotlin Standard Library,``kotlin*``,,1847,16,14,,,,,2 Kotlin Standard Library,``kotlin*``,,1847,16,14,,,,,2
`Spring <https://spring.io/>`_,``org.springframework.*``,29,483,115,4,,28,14,,35 `Spring <https://spring.io/>`_,``org.springframework.*``,29,483,115,4,,28,14,,35
Others,"``cn.hutool.core.codec``, ``com.alibaba.druid.sql``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.antlr.runtime``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.influxdb``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``org.yaml.snakeyaml``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",98,894,528,66,,18,18,,195 Others,"``cn.hutool.core.codec``, ``com.alibaba.druid.sql``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.antlr.runtime``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.influxdb``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``org.yaml.snakeyaml``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",98,899,528,66,,18,18,,195
Totals,,255,9194,1997,263,10,122,33,1,385 Totals,,255,9198,1997,263,10,122,33,1,385

View File

@@ -19,12 +19,10 @@ module Config implements DataFlow::ConfigSig {
module Flow = TaintTracking::Global<Config>; module Flow = TaintTracking::Global<Config>;
class InlineFlowTest extends InlineExpectationsTest { module InlineFlowTest implements TestSig {
InlineFlowTest() { this = "HasFlowTest" } string getARelevantTag() { result = "flow" }
override string getARelevantTag() { result = "flow" } predicate hasActualResult(Location location, string element, string tag, string value) {
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "flow" and tag = "flow" and
exists(DataFlow::Node sink | Flow::flowTo(sink) | exists(DataFlow::Node sink | Flow::flowTo(sink) |
sink.getLocation() = location and sink.getLocation() = location and
@@ -33,3 +31,5 @@ class InlineFlowTest extends InlineExpectationsTest {
) )
} }
} }
import MakeTest<InlineFlowTest>

Some files were not shown because too many files have changed in this diff Show More