mirror of
https://github.com/github/codeql.git
synced 2026-05-16 04:09:27 +02:00
Compare commits
377 Commits
codeql-cli
...
codeql-cli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ddd4ccbb4b | ||
|
|
ff030534ff | ||
|
|
b42295801b | ||
|
|
337ce65fe5 | ||
|
|
9f6c0991cf | ||
|
|
5ed9029143 | ||
|
|
75fb47c76f | ||
|
|
cd8a10d0a5 | ||
|
|
96deddf053 | ||
|
|
452685bb66 | ||
|
|
310ef79fbd | ||
|
|
d0dac03bad | ||
|
|
2dfcd1dd9c | ||
|
|
27f40e08e5 | ||
|
|
d557f6fd2e | ||
|
|
41b7922c7d | ||
|
|
19802ccb73 | ||
|
|
e63f9141e5 | ||
|
|
e476cde985 | ||
|
|
e1539889ef | ||
|
|
e24b15bbe7 | ||
|
|
9239d4042e | ||
|
|
fdc94365b4 | ||
|
|
d4f3a6d4bb | ||
|
|
00ee34c0a0 | ||
|
|
57fd397cb3 | ||
|
|
d3a4dadc7d | ||
|
|
aa9a8a0e22 | ||
|
|
36bb84d97f | ||
|
|
1ddf5fb133 | ||
|
|
29eb66d772 | ||
|
|
2af509595b | ||
|
|
7ac5791c49 | ||
|
|
ce63549425 | ||
|
|
db39c0b8be | ||
|
|
a06642944f | ||
|
|
dc0b0445ed | ||
|
|
9540beeda9 | ||
|
|
9eb9eb606e | ||
|
|
609d6011a2 | ||
|
|
6cb00992e8 | ||
|
|
d3da790191 | ||
|
|
3c8f6e3c07 | ||
|
|
4b3b1d2a8b | ||
|
|
1e752f305d | ||
|
|
08ce03cd93 | ||
|
|
3bab8c6d1d | ||
|
|
651a76c9ce | ||
|
|
c05ffd4d00 | ||
|
|
7ca3407c86 | ||
|
|
a7ec0fa900 | ||
|
|
b9d0a60ce7 | ||
|
|
b0031a0d85 | ||
|
|
1d1780b30f | ||
|
|
7dde52ced2 | ||
|
|
4efdcc22a2 | ||
|
|
f85fa87f69 | ||
|
|
2a5e0a3b77 | ||
|
|
e2652591a5 | ||
|
|
1d654d1eac | ||
|
|
1739673202 | ||
|
|
c74eac4930 | ||
|
|
cec91c4831 | ||
|
|
5101a8e9f3 | ||
|
|
136ecaf49a | ||
|
|
c3996b00d5 | ||
|
|
120f2045cd | ||
|
|
6d9cea90cb | ||
|
|
a3ca9ad27d | ||
|
|
e153a65216 | ||
|
|
914d3d86af | ||
|
|
3a7d51d2ee | ||
|
|
e607c51292 | ||
|
|
47448d9efc | ||
|
|
6c7a01d3d5 | ||
|
|
f9729bccef | ||
|
|
a3b263ee6e | ||
|
|
b2611fe198 | ||
|
|
2e7ddb479e | ||
|
|
4cbfc306ac | ||
|
|
133ec2e4af | ||
|
|
87a1ccd428 | ||
|
|
e56737e007 | ||
|
|
8c9e817c0d | ||
|
|
bb38c4d6fd | ||
|
|
1a90b388a9 | ||
|
|
055017de49 | ||
|
|
9538ac73e4 | ||
|
|
d626745ab1 | ||
|
|
e99a040884 | ||
|
|
8b44d5c39e | ||
|
|
30805d964c | ||
|
|
9b818a04f2 | ||
|
|
0bb11fa371 | ||
|
|
0547e4ccf2 | ||
|
|
d4e80c664e | ||
|
|
4498657384 | ||
|
|
28806fe5f4 | ||
|
|
6072ccd81d | ||
|
|
0ff9520575 | ||
|
|
b5165e3692 | ||
|
|
5202f963dd | ||
|
|
74c0197544 | ||
|
|
83d204d7a8 | ||
|
|
4d918b5e5f | ||
|
|
822890f2bd | ||
|
|
3e1164f82e | ||
|
|
055641e684 | ||
|
|
f5f67dd11a | ||
|
|
8cccee6eba | ||
|
|
0bd587b395 | ||
|
|
e185e9080c | ||
|
|
b2e40ac603 | ||
|
|
e5f473052d | ||
|
|
e711ba9d18 | ||
|
|
9d072a12ed | ||
|
|
672485ae38 | ||
|
|
21aff99637 | ||
|
|
dcca5d28bb | ||
|
|
50518b5622 | ||
|
|
b8e8ddf9ae | ||
|
|
a68b55b099 | ||
|
|
ed78d39d61 | ||
|
|
245edd41ff | ||
|
|
13459c8afc | ||
|
|
4b42c4447b | ||
|
|
5b11cfe006 | ||
|
|
752b126862 | ||
|
|
eaed870b31 | ||
|
|
f6baab6399 | ||
|
|
68c3c16ab3 | ||
|
|
186e3755c0 | ||
|
|
da39f15a9d | ||
|
|
522074940d | ||
|
|
b60fef88b5 | ||
|
|
21167f4b67 | ||
|
|
f308be7382 | ||
|
|
74221f4aba | ||
|
|
6f22867af9 | ||
|
|
ddeb700fd6 | ||
|
|
fc64faefcf | ||
|
|
6f2b528a32 | ||
|
|
8322a44379 | ||
|
|
f09f1c4c50 | ||
|
|
39e3254fe0 | ||
|
|
0de6511dff | ||
|
|
9f08acab7e | ||
|
|
344f7bca5b | ||
|
|
06000781e9 | ||
|
|
fc43220864 | ||
|
|
2b1f34ed9b | ||
|
|
8ba864e897 | ||
|
|
47fd64fc44 | ||
|
|
2b2ff7717e | ||
|
|
75586b0cf6 | ||
|
|
a393bff6cb | ||
|
|
90a9688310 | ||
|
|
cd39d15b40 | ||
|
|
8fc7e4be43 | ||
|
|
c297a68acf | ||
|
|
e2ef780c55 | ||
|
|
38ff584307 | ||
|
|
f933d24031 | ||
|
|
70efadac77 | ||
|
|
e87a4531d8 | ||
|
|
ac20eafecc | ||
|
|
2bba31eb02 | ||
|
|
dc464879a2 | ||
|
|
cd33e4d394 | ||
|
|
b6ce37b241 | ||
|
|
8fd8c9b04d | ||
|
|
0caea17118 | ||
|
|
34feafd4fa | ||
|
|
1f3f7e9ccc | ||
|
|
4068cc9c3a | ||
|
|
bc80c9b013 | ||
|
|
fb9b16325d | ||
|
|
fd0e318eb1 | ||
|
|
923ca134e8 | ||
|
|
b6a6ed5ba3 | ||
|
|
62730e7a4b | ||
|
|
a4538de3a3 | ||
|
|
2f7250a0b3 | ||
|
|
63ecae5426 | ||
|
|
2d78cce7a5 | ||
|
|
ee858d840e | ||
|
|
2218516685 | ||
|
|
46958e5bff | ||
|
|
af55f172ae | ||
|
|
011fc20963 | ||
|
|
6815a13a00 | ||
|
|
2af7817691 | ||
|
|
6c2713dd8b | ||
|
|
9d22ec88fd | ||
|
|
1cca377e7d | ||
|
|
ecdaeb0c10 | ||
|
|
a89be2e3f8 | ||
|
|
c998370c84 | ||
|
|
36585a7469 | ||
|
|
6dc6a78293 | ||
|
|
08b6a17097 | ||
|
|
22ebe68b1b | ||
|
|
1645fcf79c | ||
|
|
de72a765e0 | ||
|
|
9ff63b00d6 | ||
|
|
5ddfb37f29 | ||
|
|
6f24947ec6 | ||
|
|
3c3a65243f | ||
|
|
fbb3e8d780 | ||
|
|
d232283647 | ||
|
|
4eacbd1cbe | ||
|
|
6d58dd2823 | ||
|
|
3da73b9001 | ||
|
|
58dd75881c | ||
|
|
ac41451798 | ||
|
|
0c1285f5d9 | ||
|
|
7c2841f058 | ||
|
|
474c808373 | ||
|
|
08c778241d | ||
|
|
69671ce90d | ||
|
|
413375992d | ||
|
|
9125b85ff0 | ||
|
|
92453bd2c5 | ||
|
|
945bb7459a | ||
|
|
a62ad5000b | ||
|
|
135ee0d0c1 | ||
|
|
028ef6f27f | ||
|
|
48e6bdb117 | ||
|
|
db6f843641 | ||
|
|
8603609698 | ||
|
|
e468434b82 | ||
|
|
ddfcfc9b67 | ||
|
|
f6d99dc00d | ||
|
|
a743067dc8 | ||
|
|
04df56d1c0 | ||
|
|
7cfc696d62 | ||
|
|
f846915b58 | ||
|
|
c8cdbfa352 | ||
|
|
b4eadefb92 | ||
|
|
286c894f34 | ||
|
|
188915e597 | ||
|
|
76606b5995 | ||
|
|
ea9640a39d | ||
|
|
d408105fad | ||
|
|
5ef71e6ef3 | ||
|
|
9e8e2e2b48 | ||
|
|
e7b091086d | ||
|
|
aafa5762ad | ||
|
|
98e6fc8a88 | ||
|
|
0e6bb28016 | ||
|
|
a980f26fda | ||
|
|
9f4107d211 | ||
|
|
b9ea4a8709 | ||
|
|
fd9199c0c0 | ||
|
|
d7ed325b3f | ||
|
|
f4310898b3 | ||
|
|
1cd42ea668 | ||
|
|
8040d9cfcf | ||
|
|
e6e52a3b32 | ||
|
|
c616f5784d | ||
|
|
9e097f5430 | ||
|
|
0d4cb1e6ce | ||
|
|
6eb4525ab2 | ||
|
|
e812029c03 | ||
|
|
dc022430ee | ||
|
|
412bd32f45 | ||
|
|
b84c03672d | ||
|
|
bca6cecd1c | ||
|
|
78e3906ea7 | ||
|
|
cce3780481 | ||
|
|
f0c5a80d1a | ||
|
|
0ff36cd083 | ||
|
|
b11d11c0c9 | ||
|
|
9034d74663 | ||
|
|
a0b7f267ff | ||
|
|
0234e77d2f | ||
|
|
b8809a20d8 | ||
|
|
b639a8d183 | ||
|
|
dbcd4d6d5d | ||
|
|
2d4176bec0 | ||
|
|
dbd393b77a | ||
|
|
974c7b0898 | ||
|
|
74ac234f1c | ||
|
|
8740e879b4 | ||
|
|
a546b38ee0 | ||
|
|
6960a7b97e | ||
|
|
ef972159a6 | ||
|
|
4cfd978bfe | ||
|
|
b92758883b | ||
|
|
e2bd792fc2 | ||
|
|
739fe75194 | ||
|
|
58de6d143f | ||
|
|
747ab122c3 | ||
|
|
8564c9001a | ||
|
|
9500c9c8bc | ||
|
|
35baa1c3df | ||
|
|
83b4070f31 | ||
|
|
281f25403d | ||
|
|
bc10fd94cb | ||
|
|
0e9fcc6c39 | ||
|
|
157f56f48a | ||
|
|
f36bb8baaf | ||
|
|
842f617bc1 | ||
|
|
be150f269b | ||
|
|
2654e27123 | ||
|
|
6b2460d4a1 | ||
|
|
060862ab3b | ||
|
|
e607953b9c | ||
|
|
9a859334d4 | ||
|
|
6c59333716 | ||
|
|
7dae6122d9 | ||
|
|
ca9d5439f0 | ||
|
|
7a7ec06819 | ||
|
|
1a4fd7bc7d | ||
|
|
2b2ac82fb7 | ||
|
|
c616eb1473 | ||
|
|
38579ef25b | ||
|
|
a80d50cbc0 | ||
|
|
a1d8dfb524 | ||
|
|
c844f5382f | ||
|
|
f9fea15a52 | ||
|
|
364de55b8d | ||
|
|
cd11ef3bf6 | ||
|
|
c3462be2c9 | ||
|
|
4ca006ba3d | ||
|
|
88032afdc3 | ||
|
|
ec772fb6b2 | ||
|
|
32ef40c77b | ||
|
|
77099fe9d0 | ||
|
|
9710aeecbf | ||
|
|
1efe1e0d10 | ||
|
|
556cdbaa21 | ||
|
|
37775407a9 | ||
|
|
340897f262 | ||
|
|
a23750a9c7 | ||
|
|
c65d1d9a50 | ||
|
|
10bca3544c | ||
|
|
4af3775b72 | ||
|
|
5f78bbbf52 | ||
|
|
543bd28b03 | ||
|
|
d324f9397c | ||
|
|
25da904314 | ||
|
|
4666024419 | ||
|
|
91f99ed2a1 | ||
|
|
fad7e9489b | ||
|
|
8a412dc5fd | ||
|
|
02f500b9c2 | ||
|
|
84b38b6c32 | ||
|
|
dd17271ec8 | ||
|
|
db40ccae81 | ||
|
|
fed0a06353 | ||
|
|
7201b3e116 | ||
|
|
8536f5f5a2 | ||
|
|
bd92403b42 | ||
|
|
11154a9409 | ||
|
|
fed6a97eb8 | ||
|
|
8a4b043cb1 | ||
|
|
62e729501c | ||
|
|
97264b5dda | ||
|
|
c15ddf6e92 | ||
|
|
2ddf445caf | ||
|
|
44afa34e37 | ||
|
|
8d6cac76cc | ||
|
|
aafae24ef2 | ||
|
|
8d556ed1e1 | ||
|
|
378db7de87 | ||
|
|
5264936fc3 | ||
|
|
272e4f6cf9 | ||
|
|
2dc38aee54 | ||
|
|
99ed4a1a89 | ||
|
|
fd64ff9ef1 | ||
|
|
c40ffab093 | ||
|
|
672e4a3d72 | ||
|
|
60993214d5 | ||
|
|
01e345c2cc | ||
|
|
8535e6f281 | ||
|
|
8170f01b66 |
@@ -1,11 +1,23 @@
|
||||
{ "provide": [ "ruby/.codeqlmanifest.json",
|
||||
"*/ql/src/qlpack.yml",
|
||||
"*/ql/lib/qlpack.yml",
|
||||
"*/ql/test/qlpack.yml",
|
||||
"cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml",
|
||||
"*/ql/examples/qlpack.yml",
|
||||
"*/upgrades/qlpack.yml",
|
||||
"javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml",
|
||||
"javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml",
|
||||
"misc/legacy-support/*/qlpack.yml",
|
||||
"misc/suite-helpers/qlpack.yml" ] }
|
||||
{
|
||||
"provide": [
|
||||
"*/ql/src/qlpack.yml",
|
||||
"*/ql/lib/qlpack.yml",
|
||||
"*/ql/test/qlpack.yml",
|
||||
"*/ql/examples/qlpack.yml",
|
||||
"*/upgrades/qlpack.yml",
|
||||
"cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml",
|
||||
"javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml",
|
||||
"javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml",
|
||||
"misc/legacy-support/*/qlpack.yml",
|
||||
"misc/suite-helpers/qlpack.yml",
|
||||
"ruby/extractor-pack/codeql-extractor.yml",
|
||||
"ruby/ql/consistency-queries/qlpack.yml"
|
||||
],
|
||||
"versionPolicies": {
|
||||
"default": {
|
||||
"requireChangeNotes": true,
|
||||
"committedPrereleaseSuffix": "dev",
|
||||
"committedVersion": "nextPatchRelease"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
2
.github/workflows/ruby-dataset-measure.yml
vendored
2
.github/workflows/ruby-dataset-measure.yml
vendored
@@ -41,7 +41,7 @@ jobs:
|
||||
- name: Create database
|
||||
run: |
|
||||
codeql database create \
|
||||
--search-path "${{ github.workspace }}/ruby" \
|
||||
--search-path "${{ github.workspace }}/ruby/extractor-pack" \
|
||||
--threads 4 \
|
||||
--language ruby --source-root "${{ github.workspace }}/repo" \
|
||||
"${{ runner.temp }}/database"
|
||||
|
||||
4
.github/workflows/ruby-qltest.yml
vendored
4
.github/workflows/ruby-qltest.yml
vendored
@@ -32,14 +32,14 @@ jobs:
|
||||
- uses: ./ruby/actions/create-extractor-pack
|
||||
- name: Run QL tests
|
||||
run: |
|
||||
codeql test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}/ruby" --additional-packs "${{ github.workspace }}" --consistency-queries ql/consistency-queries ql/test
|
||||
codeql test run --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
- name: Check QL formatting
|
||||
run: find ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 codeql query format --check-only
|
||||
- name: Check QL compilation
|
||||
run: |
|
||||
codeql query compile --check-only --threads=4 --warnings=error --search-path "${{ github.workspace }}/ruby" --additional-packs "${{ github.workspace }}" "ql/src" "ql/examples"
|
||||
codeql query compile --check-only --threads=4 --warnings=error "ql/src" "ql/examples"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
- name: Check DB upgrade scripts
|
||||
|
||||
@@ -460,9 +460,10 @@
|
||||
"javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
|
||||
"python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll"
|
||||
],
|
||||
"ReDoS Util Python/JS": [
|
||||
"ReDoS Util Python/JS/Ruby": [
|
||||
"javascript/ql/lib/semmle/javascript/security/performance/ReDoSUtil.qll",
|
||||
"python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll"
|
||||
"python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/performance/ReDoSUtil.qll"
|
||||
],
|
||||
"ReDoS Exponential Python/JS": [
|
||||
"javascript/ql/lib/semmle/javascript/security/performance/ExponentialBackTracking.qll",
|
||||
@@ -471,7 +472,12 @@
|
||||
"ReDoS Polynomial Python/JS": [
|
||||
"javascript/ql/lib/semmle/javascript/security/performance/SuperlinearBackTracking.qll",
|
||||
"python/ql/lib/semmle/python/security/performance/SuperlinearBackTracking.qll",
|
||||
"ruby/ql/lib/codeql/ruby/regexp/SuperlinearBackTracking.qll"
|
||||
"ruby/ql/lib/codeql/ruby/security/performance/SuperlinearBackTracking.qll"
|
||||
],
|
||||
"BadTagFilterQuery Python/JS/Ruby": [
|
||||
"javascript/ql/lib/semmle/javascript/security/BadTagFilterQuery.qll",
|
||||
"python/ql/lib/semmle/python/security/BadTagFilterQuery.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/BadTagFilterQuery.qll"
|
||||
],
|
||||
"CFG": [
|
||||
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll",
|
||||
|
||||
7
cpp/ql/lib/CHANGELOG.md
Normal file
7
cpp/ql/lib/CHANGELOG.md
Normal file
@@ -0,0 +1,7 @@
|
||||
## 0.0.4
|
||||
|
||||
### New Features
|
||||
|
||||
* The QL library `semmle.code.cpp.commons.Exclusions` now contains a predicate
|
||||
`isFromSystemMacroDefinition` for identifying code that originates from a
|
||||
macro outside the project being analyzed.
|
||||
7
cpp/ql/lib/change-notes/released/0.0.4.md
Normal file
7
cpp/ql/lib/change-notes/released/0.0.4.md
Normal file
@@ -0,0 +1,7 @@
|
||||
## 0.0.4
|
||||
|
||||
### New Features
|
||||
|
||||
* The QL library `semmle.code.cpp.commons.Exclusions` now contains a predicate
|
||||
`isFromSystemMacroDefinition` for identifying code that originates from a
|
||||
macro outside the project being analyzed.
|
||||
2
cpp/ql/lib/codeql-pack.release.yml
Normal file
2
cpp/ql/lib/codeql-pack.release.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.0.4
|
||||
@@ -1,7 +1,8 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.0.2
|
||||
version: 0.0.4
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
library: true
|
||||
dependencies:
|
||||
codeql/cpp-upgrades: 0.0.2
|
||||
codeql/cpp-upgrades: 0.0.3
|
||||
|
||||
@@ -289,6 +289,7 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
exists(Node n | node.asNode() = n |
|
||||
config.isBarrier(n)
|
||||
@@ -307,11 +308,23 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sourceNode(NodeEx node, Configuration config) { config.isSource(node.asNode()) }
|
||||
private predicate sourceNode(NodeEx node, Configuration config) {
|
||||
config.isSource(node.asNode()) and
|
||||
not fullBarrier(node, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) }
|
||||
|
||||
/** Provides the relevant barriers for a step from `node1` to `node2`. */
|
||||
pragma[inline]
|
||||
private predicate stepFilter(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
@@ -320,16 +333,14 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.asNode() = n and
|
||||
node2.isImplicitReadNode(n, false)
|
||||
node2.isImplicitReadNode(n, false) and
|
||||
not fullBarrier(node1, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -342,16 +353,14 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.isImplicitReadNode(n, true) and
|
||||
node2.asNode() = n
|
||||
node2.asNode() = n and
|
||||
not fullBarrier(node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -363,10 +372,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
@@ -380,16 +386,14 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
|
||||
private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) {
|
||||
read(node1.asNode(), c, node2.asNode())
|
||||
read(node1.asNode(), c, node2.asNode()) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
node2.isImplicitReadNode(n, true) and
|
||||
@@ -402,7 +406,8 @@ private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
read(_, tc.getContent(), _, config)
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -451,63 +456,59 @@ private module Stage1 {
|
||||
* argument in a call.
|
||||
*/
|
||||
predicate fwdFlow(NodeEx node, Cc cc, Configuration config) {
|
||||
not fullBarrier(node, config) and
|
||||
(
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config) and
|
||||
not outBarrier(mid, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config) and
|
||||
not inBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -547,7 +548,8 @@ private module Stage1 {
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
viableReturnPosOutEx(call, pos, out)
|
||||
viableReturnPosOutEx(call, pos, out) and
|
||||
not fullBarrier(out, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -773,6 +775,7 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
@@ -1019,12 +1022,14 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,9 +1147,8 @@ private module Stage2 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1159,9 +1163,8 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1171,10 +1174,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1230,6 +1231,11 @@ private module Stage2 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -1306,7 +1312,7 @@ private module Stage2 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -1341,9 +1347,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1353,9 +1358,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1365,9 +1369,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1707,12 +1710,14 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1837,9 +1842,8 @@ private module Stage3 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1854,9 +1858,8 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1866,10 +1869,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1925,6 +1926,11 @@ private module Stage3 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2001,7 +2007,7 @@ private module Stage3 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2036,9 +2042,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2048,9 +2053,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2060,9 +2064,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2473,12 +2476,14 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2603,9 +2608,8 @@ private module Stage4 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2620,9 +2624,8 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2632,10 +2635,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2691,6 +2692,11 @@ private module Stage4 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2767,7 +2773,7 @@ private module Stage4 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2802,9 +2808,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2814,9 +2819,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2826,9 +2830,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -289,6 +289,7 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
exists(Node n | node.asNode() = n |
|
||||
config.isBarrier(n)
|
||||
@@ -307,11 +308,23 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sourceNode(NodeEx node, Configuration config) { config.isSource(node.asNode()) }
|
||||
private predicate sourceNode(NodeEx node, Configuration config) {
|
||||
config.isSource(node.asNode()) and
|
||||
not fullBarrier(node, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) }
|
||||
|
||||
/** Provides the relevant barriers for a step from `node1` to `node2`. */
|
||||
pragma[inline]
|
||||
private predicate stepFilter(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
@@ -320,16 +333,14 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.asNode() = n and
|
||||
node2.isImplicitReadNode(n, false)
|
||||
node2.isImplicitReadNode(n, false) and
|
||||
not fullBarrier(node1, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -342,16 +353,14 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.isImplicitReadNode(n, true) and
|
||||
node2.asNode() = n
|
||||
node2.asNode() = n and
|
||||
not fullBarrier(node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -363,10 +372,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
@@ -380,16 +386,14 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
|
||||
private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) {
|
||||
read(node1.asNode(), c, node2.asNode())
|
||||
read(node1.asNode(), c, node2.asNode()) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
node2.isImplicitReadNode(n, true) and
|
||||
@@ -402,7 +406,8 @@ private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
read(_, tc.getContent(), _, config)
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -451,63 +456,59 @@ private module Stage1 {
|
||||
* argument in a call.
|
||||
*/
|
||||
predicate fwdFlow(NodeEx node, Cc cc, Configuration config) {
|
||||
not fullBarrier(node, config) and
|
||||
(
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config) and
|
||||
not outBarrier(mid, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config) and
|
||||
not inBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -547,7 +548,8 @@ private module Stage1 {
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
viableReturnPosOutEx(call, pos, out)
|
||||
viableReturnPosOutEx(call, pos, out) and
|
||||
not fullBarrier(out, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -773,6 +775,7 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
@@ -1019,12 +1022,14 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,9 +1147,8 @@ private module Stage2 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1159,9 +1163,8 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1171,10 +1174,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1230,6 +1231,11 @@ private module Stage2 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -1306,7 +1312,7 @@ private module Stage2 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -1341,9 +1347,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1353,9 +1358,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1365,9 +1369,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1707,12 +1710,14 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1837,9 +1842,8 @@ private module Stage3 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1854,9 +1858,8 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1866,10 +1869,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1925,6 +1926,11 @@ private module Stage3 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2001,7 +2007,7 @@ private module Stage3 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2036,9 +2042,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2048,9 +2053,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2060,9 +2064,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2473,12 +2476,14 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2603,9 +2608,8 @@ private module Stage4 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2620,9 +2624,8 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2632,10 +2635,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2691,6 +2692,11 @@ private module Stage4 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2767,7 +2773,7 @@ private module Stage4 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2802,9 +2808,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2814,9 +2819,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2826,9 +2830,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -289,6 +289,7 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
exists(Node n | node.asNode() = n |
|
||||
config.isBarrier(n)
|
||||
@@ -307,11 +308,23 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sourceNode(NodeEx node, Configuration config) { config.isSource(node.asNode()) }
|
||||
private predicate sourceNode(NodeEx node, Configuration config) {
|
||||
config.isSource(node.asNode()) and
|
||||
not fullBarrier(node, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) }
|
||||
|
||||
/** Provides the relevant barriers for a step from `node1` to `node2`. */
|
||||
pragma[inline]
|
||||
private predicate stepFilter(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
@@ -320,16 +333,14 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.asNode() = n and
|
||||
node2.isImplicitReadNode(n, false)
|
||||
node2.isImplicitReadNode(n, false) and
|
||||
not fullBarrier(node1, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -342,16 +353,14 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.isImplicitReadNode(n, true) and
|
||||
node2.asNode() = n
|
||||
node2.asNode() = n and
|
||||
not fullBarrier(node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -363,10 +372,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
@@ -380,16 +386,14 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
|
||||
private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) {
|
||||
read(node1.asNode(), c, node2.asNode())
|
||||
read(node1.asNode(), c, node2.asNode()) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
node2.isImplicitReadNode(n, true) and
|
||||
@@ -402,7 +406,8 @@ private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
read(_, tc.getContent(), _, config)
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -451,63 +456,59 @@ private module Stage1 {
|
||||
* argument in a call.
|
||||
*/
|
||||
predicate fwdFlow(NodeEx node, Cc cc, Configuration config) {
|
||||
not fullBarrier(node, config) and
|
||||
(
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config) and
|
||||
not outBarrier(mid, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config) and
|
||||
not inBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -547,7 +548,8 @@ private module Stage1 {
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
viableReturnPosOutEx(call, pos, out)
|
||||
viableReturnPosOutEx(call, pos, out) and
|
||||
not fullBarrier(out, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -773,6 +775,7 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
@@ -1019,12 +1022,14 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,9 +1147,8 @@ private module Stage2 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1159,9 +1163,8 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1171,10 +1174,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1230,6 +1231,11 @@ private module Stage2 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -1306,7 +1312,7 @@ private module Stage2 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -1341,9 +1347,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1353,9 +1358,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1365,9 +1369,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1707,12 +1710,14 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1837,9 +1842,8 @@ private module Stage3 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1854,9 +1858,8 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1866,10 +1869,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1925,6 +1926,11 @@ private module Stage3 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2001,7 +2007,7 @@ private module Stage3 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2036,9 +2042,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2048,9 +2053,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2060,9 +2064,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2473,12 +2476,14 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2603,9 +2608,8 @@ private module Stage4 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2620,9 +2624,8 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2632,10 +2635,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2691,6 +2692,11 @@ private module Stage4 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2767,7 +2773,7 @@ private module Stage4 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2802,9 +2808,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2814,9 +2819,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2826,9 +2830,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -289,6 +289,7 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
exists(Node n | node.asNode() = n |
|
||||
config.isBarrier(n)
|
||||
@@ -307,11 +308,23 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sourceNode(NodeEx node, Configuration config) { config.isSource(node.asNode()) }
|
||||
private predicate sourceNode(NodeEx node, Configuration config) {
|
||||
config.isSource(node.asNode()) and
|
||||
not fullBarrier(node, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) }
|
||||
|
||||
/** Provides the relevant barriers for a step from `node1` to `node2`. */
|
||||
pragma[inline]
|
||||
private predicate stepFilter(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
@@ -320,16 +333,14 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.asNode() = n and
|
||||
node2.isImplicitReadNode(n, false)
|
||||
node2.isImplicitReadNode(n, false) and
|
||||
not fullBarrier(node1, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -342,16 +353,14 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.isImplicitReadNode(n, true) and
|
||||
node2.asNode() = n
|
||||
node2.asNode() = n and
|
||||
not fullBarrier(node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -363,10 +372,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
@@ -380,16 +386,14 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
|
||||
private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) {
|
||||
read(node1.asNode(), c, node2.asNode())
|
||||
read(node1.asNode(), c, node2.asNode()) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
node2.isImplicitReadNode(n, true) and
|
||||
@@ -402,7 +406,8 @@ private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
read(_, tc.getContent(), _, config)
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -451,63 +456,59 @@ private module Stage1 {
|
||||
* argument in a call.
|
||||
*/
|
||||
predicate fwdFlow(NodeEx node, Cc cc, Configuration config) {
|
||||
not fullBarrier(node, config) and
|
||||
(
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config) and
|
||||
not outBarrier(mid, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config) and
|
||||
not inBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -547,7 +548,8 @@ private module Stage1 {
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
viableReturnPosOutEx(call, pos, out)
|
||||
viableReturnPosOutEx(call, pos, out) and
|
||||
not fullBarrier(out, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -773,6 +775,7 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
@@ -1019,12 +1022,14 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,9 +1147,8 @@ private module Stage2 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1159,9 +1163,8 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1171,10 +1174,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1230,6 +1231,11 @@ private module Stage2 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -1306,7 +1312,7 @@ private module Stage2 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -1341,9 +1347,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1353,9 +1358,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1365,9 +1369,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1707,12 +1710,14 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1837,9 +1842,8 @@ private module Stage3 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1854,9 +1858,8 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1866,10 +1869,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1925,6 +1926,11 @@ private module Stage3 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2001,7 +2007,7 @@ private module Stage3 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2036,9 +2042,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2048,9 +2053,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2060,9 +2064,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2473,12 +2476,14 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2603,9 +2608,8 @@ private module Stage4 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2620,9 +2624,8 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2632,10 +2635,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2691,6 +2692,11 @@ private module Stage4 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2767,7 +2773,7 @@ private module Stage4 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2802,9 +2808,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2814,9 +2819,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2826,9 +2830,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,19 @@ private import tainttracking1.TaintTrackingParameter::Private
|
||||
private import tainttracking1.TaintTrackingParameter::Public
|
||||
|
||||
module Consistency {
|
||||
private newtype TConsistencyConfiguration = MkConsistencyConfiguration()
|
||||
|
||||
/** A class for configuring the consistency queries. */
|
||||
class ConsistencyConfiguration extends TConsistencyConfiguration {
|
||||
string toString() { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */
|
||||
predicate postWithInFlowExclude(Node n) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */
|
||||
predicate argHasPostUpdateExclude(ArgumentNode n) { none() }
|
||||
}
|
||||
|
||||
private class RelevantNode extends Node {
|
||||
RelevantNode() {
|
||||
this instanceof ArgumentNode or
|
||||
@@ -164,7 +177,7 @@ module Consistency {
|
||||
|
||||
query predicate argHasPostUpdate(ArgumentNode n, string msg) {
|
||||
not hasPost(n) and
|
||||
not isImmutableOrUnobservable(n) and
|
||||
not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and
|
||||
msg = "ArgumentNode is missing PostUpdateNode."
|
||||
}
|
||||
|
||||
@@ -177,6 +190,7 @@ module Consistency {
|
||||
isPostUpdateNode(n) and
|
||||
not clearsContent(n, _) and
|
||||
simpleLocalFlowStep(_, n) and
|
||||
not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
|
||||
msg = "PostUpdateNode should not be the target of local flow."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,6 +289,7 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
exists(Node n | node.asNode() = n |
|
||||
config.isBarrier(n)
|
||||
@@ -307,11 +308,23 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sourceNode(NodeEx node, Configuration config) { config.isSource(node.asNode()) }
|
||||
private predicate sourceNode(NodeEx node, Configuration config) {
|
||||
config.isSource(node.asNode()) and
|
||||
not fullBarrier(node, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) }
|
||||
|
||||
/** Provides the relevant barriers for a step from `node1` to `node2`. */
|
||||
pragma[inline]
|
||||
private predicate stepFilter(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
@@ -320,16 +333,14 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.asNode() = n and
|
||||
node2.isImplicitReadNode(n, false)
|
||||
node2.isImplicitReadNode(n, false) and
|
||||
not fullBarrier(node1, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -342,16 +353,14 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.isImplicitReadNode(n, true) and
|
||||
node2.asNode() = n
|
||||
node2.asNode() = n and
|
||||
not fullBarrier(node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -363,10 +372,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
@@ -380,16 +386,14 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
|
||||
private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) {
|
||||
read(node1.asNode(), c, node2.asNode())
|
||||
read(node1.asNode(), c, node2.asNode()) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
node2.isImplicitReadNode(n, true) and
|
||||
@@ -402,7 +406,8 @@ private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
read(_, tc.getContent(), _, config)
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -451,63 +456,59 @@ private module Stage1 {
|
||||
* argument in a call.
|
||||
*/
|
||||
predicate fwdFlow(NodeEx node, Cc cc, Configuration config) {
|
||||
not fullBarrier(node, config) and
|
||||
(
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config) and
|
||||
not outBarrier(mid, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config) and
|
||||
not inBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -547,7 +548,8 @@ private module Stage1 {
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
viableReturnPosOutEx(call, pos, out)
|
||||
viableReturnPosOutEx(call, pos, out) and
|
||||
not fullBarrier(out, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -773,6 +775,7 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
@@ -1019,12 +1022,14 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,9 +1147,8 @@ private module Stage2 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1159,9 +1163,8 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1171,10 +1174,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1230,6 +1231,11 @@ private module Stage2 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -1306,7 +1312,7 @@ private module Stage2 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -1341,9 +1347,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1353,9 +1358,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1365,9 +1369,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1707,12 +1710,14 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1837,9 +1842,8 @@ private module Stage3 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1854,9 +1858,8 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1866,10 +1869,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1925,6 +1926,11 @@ private module Stage3 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2001,7 +2007,7 @@ private module Stage3 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2036,9 +2042,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2048,9 +2053,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2060,9 +2064,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2473,12 +2476,14 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2603,9 +2608,8 @@ private module Stage4 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2620,9 +2624,8 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2632,10 +2635,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2691,6 +2692,11 @@ private module Stage4 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2767,7 +2773,7 @@ private module Stage4 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2802,9 +2808,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2814,9 +2819,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2826,9 +2830,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ private import cpp
|
||||
private import DataFlowUtil
|
||||
private import DataFlowDispatch
|
||||
private import FlowVar
|
||||
private import DataFlowImplConsistency
|
||||
|
||||
/** Gets the callable in which this node occurs. */
|
||||
DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() }
|
||||
@@ -259,27 +260,6 @@ class Unit extends TUnit {
|
||||
string toString() { result = "unit" }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `n` does not require a `PostUpdateNode` as it either cannot be
|
||||
* modified or its modification cannot be observed, for example if it is a
|
||||
* freshly created object that is not saved in a variable.
|
||||
*
|
||||
* This predicate is only used for consistency checks.
|
||||
*/
|
||||
predicate isImmutableOrUnobservable(Node n) {
|
||||
// Is the null pointer (or something that's not really a pointer)
|
||||
exists(n.asExpr().getValue())
|
||||
or
|
||||
// Isn't a pointer or is a pointer to const
|
||||
forall(DerivedType dt | dt = n.asExpr().getActualType() |
|
||||
dt.getBaseType().isConst()
|
||||
or
|
||||
dt.getBaseType() instanceof RoutineType
|
||||
)
|
||||
// The above list of cases isn't exhaustive, but it narrows down the
|
||||
// consistency alerts enough that most of them are interesting.
|
||||
}
|
||||
|
||||
/** Holds if `n` should be hidden from path explanations. */
|
||||
predicate nodeIsHidden(Node n) { none() }
|
||||
|
||||
@@ -302,3 +282,19 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves
|
||||
* by default as a heuristic.
|
||||
*/
|
||||
predicate allowParameterReturnInSelf(ParameterNode p) { none() }
|
||||
|
||||
private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration {
|
||||
override predicate argHasPostUpdateExclude(ArgumentNode n) {
|
||||
// Is the null pointer (or something that's not really a pointer)
|
||||
exists(n.asExpr().getValue())
|
||||
or
|
||||
// Isn't a pointer or is a pointer to const
|
||||
forall(DerivedType dt | dt = n.asExpr().getActualType() |
|
||||
dt.getBaseType().isConst()
|
||||
or
|
||||
dt.getBaseType() instanceof RoutineType
|
||||
)
|
||||
// The above list of cases isn't exhaustive, but it narrows down the
|
||||
// consistency alerts enough that most of them are interesting.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -484,8 +484,9 @@ module TaintedWithPath {
|
||||
/** Gets the element that `pathNode` wraps, if any. */
|
||||
Element getElementFromPathNode(PathNode pathNode) {
|
||||
exists(DataFlow::Node node | node = pathNode.(WrapPathNode).inner().getNode() |
|
||||
result = node.asExpr() or
|
||||
result = node.asParameter()
|
||||
result = node.asInstruction().getAST()
|
||||
or
|
||||
result = node.asOperand().getDef().getAST()
|
||||
)
|
||||
or
|
||||
result = pathNode.(EndpointPathNode).inner()
|
||||
|
||||
@@ -289,6 +289,7 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
exists(Node n | node.asNode() = n |
|
||||
config.isBarrier(n)
|
||||
@@ -307,11 +308,23 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sourceNode(NodeEx node, Configuration config) { config.isSource(node.asNode()) }
|
||||
private predicate sourceNode(NodeEx node, Configuration config) {
|
||||
config.isSource(node.asNode()) and
|
||||
not fullBarrier(node, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) }
|
||||
|
||||
/** Provides the relevant barriers for a step from `node1` to `node2`. */
|
||||
pragma[inline]
|
||||
private predicate stepFilter(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
@@ -320,16 +333,14 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.asNode() = n and
|
||||
node2.isImplicitReadNode(n, false)
|
||||
node2.isImplicitReadNode(n, false) and
|
||||
not fullBarrier(node1, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -342,16 +353,14 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.isImplicitReadNode(n, true) and
|
||||
node2.asNode() = n
|
||||
node2.asNode() = n and
|
||||
not fullBarrier(node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -363,10 +372,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
@@ -380,16 +386,14 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
|
||||
private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) {
|
||||
read(node1.asNode(), c, node2.asNode())
|
||||
read(node1.asNode(), c, node2.asNode()) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
node2.isImplicitReadNode(n, true) and
|
||||
@@ -402,7 +406,8 @@ private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
read(_, tc.getContent(), _, config)
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -451,63 +456,59 @@ private module Stage1 {
|
||||
* argument in a call.
|
||||
*/
|
||||
predicate fwdFlow(NodeEx node, Cc cc, Configuration config) {
|
||||
not fullBarrier(node, config) and
|
||||
(
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config) and
|
||||
not outBarrier(mid, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config) and
|
||||
not inBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -547,7 +548,8 @@ private module Stage1 {
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
viableReturnPosOutEx(call, pos, out)
|
||||
viableReturnPosOutEx(call, pos, out) and
|
||||
not fullBarrier(out, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -773,6 +775,7 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
@@ -1019,12 +1022,14 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,9 +1147,8 @@ private module Stage2 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1159,9 +1163,8 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1171,10 +1174,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1230,6 +1231,11 @@ private module Stage2 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -1306,7 +1312,7 @@ private module Stage2 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -1341,9 +1347,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1353,9 +1358,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1365,9 +1369,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1707,12 +1710,14 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1837,9 +1842,8 @@ private module Stage3 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1854,9 +1858,8 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1866,10 +1869,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1925,6 +1926,11 @@ private module Stage3 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2001,7 +2007,7 @@ private module Stage3 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2036,9 +2042,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2048,9 +2053,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2060,9 +2064,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2473,12 +2476,14 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2603,9 +2608,8 @@ private module Stage4 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2620,9 +2624,8 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2632,10 +2635,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2691,6 +2692,11 @@ private module Stage4 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2767,7 +2773,7 @@ private module Stage4 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2802,9 +2808,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2814,9 +2819,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2826,9 +2830,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -289,6 +289,7 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
exists(Node n | node.asNode() = n |
|
||||
config.isBarrier(n)
|
||||
@@ -307,11 +308,23 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sourceNode(NodeEx node, Configuration config) { config.isSource(node.asNode()) }
|
||||
private predicate sourceNode(NodeEx node, Configuration config) {
|
||||
config.isSource(node.asNode()) and
|
||||
not fullBarrier(node, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) }
|
||||
|
||||
/** Provides the relevant barriers for a step from `node1` to `node2`. */
|
||||
pragma[inline]
|
||||
private predicate stepFilter(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
@@ -320,16 +333,14 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.asNode() = n and
|
||||
node2.isImplicitReadNode(n, false)
|
||||
node2.isImplicitReadNode(n, false) and
|
||||
not fullBarrier(node1, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -342,16 +353,14 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.isImplicitReadNode(n, true) and
|
||||
node2.asNode() = n
|
||||
node2.asNode() = n and
|
||||
not fullBarrier(node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -363,10 +372,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
@@ -380,16 +386,14 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
|
||||
private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) {
|
||||
read(node1.asNode(), c, node2.asNode())
|
||||
read(node1.asNode(), c, node2.asNode()) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
node2.isImplicitReadNode(n, true) and
|
||||
@@ -402,7 +406,8 @@ private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
read(_, tc.getContent(), _, config)
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -451,63 +456,59 @@ private module Stage1 {
|
||||
* argument in a call.
|
||||
*/
|
||||
predicate fwdFlow(NodeEx node, Cc cc, Configuration config) {
|
||||
not fullBarrier(node, config) and
|
||||
(
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config) and
|
||||
not outBarrier(mid, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config) and
|
||||
not inBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -547,7 +548,8 @@ private module Stage1 {
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
viableReturnPosOutEx(call, pos, out)
|
||||
viableReturnPosOutEx(call, pos, out) and
|
||||
not fullBarrier(out, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -773,6 +775,7 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
@@ -1019,12 +1022,14 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,9 +1147,8 @@ private module Stage2 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1159,9 +1163,8 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1171,10 +1174,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1230,6 +1231,11 @@ private module Stage2 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -1306,7 +1312,7 @@ private module Stage2 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -1341,9 +1347,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1353,9 +1358,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1365,9 +1369,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1707,12 +1710,14 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1837,9 +1842,8 @@ private module Stage3 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1854,9 +1858,8 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1866,10 +1869,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1925,6 +1926,11 @@ private module Stage3 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2001,7 +2007,7 @@ private module Stage3 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2036,9 +2042,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2048,9 +2053,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2060,9 +2064,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2473,12 +2476,14 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2603,9 +2608,8 @@ private module Stage4 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2620,9 +2624,8 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2632,10 +2635,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2691,6 +2692,11 @@ private module Stage4 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2767,7 +2773,7 @@ private module Stage4 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2802,9 +2808,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2814,9 +2819,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2826,9 +2830,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -289,6 +289,7 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
exists(Node n | node.asNode() = n |
|
||||
config.isBarrier(n)
|
||||
@@ -307,11 +308,23 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sourceNode(NodeEx node, Configuration config) { config.isSource(node.asNode()) }
|
||||
private predicate sourceNode(NodeEx node, Configuration config) {
|
||||
config.isSource(node.asNode()) and
|
||||
not fullBarrier(node, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) }
|
||||
|
||||
/** Provides the relevant barriers for a step from `node1` to `node2`. */
|
||||
pragma[inline]
|
||||
private predicate stepFilter(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
@@ -320,16 +333,14 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.asNode() = n and
|
||||
node2.isImplicitReadNode(n, false)
|
||||
node2.isImplicitReadNode(n, false) and
|
||||
not fullBarrier(node1, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -342,16 +353,14 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.isImplicitReadNode(n, true) and
|
||||
node2.asNode() = n
|
||||
node2.asNode() = n and
|
||||
not fullBarrier(node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -363,10 +372,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
@@ -380,16 +386,14 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
|
||||
private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) {
|
||||
read(node1.asNode(), c, node2.asNode())
|
||||
read(node1.asNode(), c, node2.asNode()) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
node2.isImplicitReadNode(n, true) and
|
||||
@@ -402,7 +406,8 @@ private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
read(_, tc.getContent(), _, config)
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -451,63 +456,59 @@ private module Stage1 {
|
||||
* argument in a call.
|
||||
*/
|
||||
predicate fwdFlow(NodeEx node, Cc cc, Configuration config) {
|
||||
not fullBarrier(node, config) and
|
||||
(
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config) and
|
||||
not outBarrier(mid, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config) and
|
||||
not inBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -547,7 +548,8 @@ private module Stage1 {
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
viableReturnPosOutEx(call, pos, out)
|
||||
viableReturnPosOutEx(call, pos, out) and
|
||||
not fullBarrier(out, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -773,6 +775,7 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
@@ -1019,12 +1022,14 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,9 +1147,8 @@ private module Stage2 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1159,9 +1163,8 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1171,10 +1174,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1230,6 +1231,11 @@ private module Stage2 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -1306,7 +1312,7 @@ private module Stage2 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -1341,9 +1347,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1353,9 +1358,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1365,9 +1369,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1707,12 +1710,14 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1837,9 +1842,8 @@ private module Stage3 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1854,9 +1858,8 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1866,10 +1869,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1925,6 +1926,11 @@ private module Stage3 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2001,7 +2007,7 @@ private module Stage3 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2036,9 +2042,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2048,9 +2053,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2060,9 +2064,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2473,12 +2476,14 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2603,9 +2608,8 @@ private module Stage4 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2620,9 +2624,8 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2632,10 +2635,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2691,6 +2692,11 @@ private module Stage4 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2767,7 +2773,7 @@ private module Stage4 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2802,9 +2808,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2814,9 +2819,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2826,9 +2830,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -289,6 +289,7 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
exists(Node n | node.asNode() = n |
|
||||
config.isBarrier(n)
|
||||
@@ -307,11 +308,23 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sourceNode(NodeEx node, Configuration config) { config.isSource(node.asNode()) }
|
||||
private predicate sourceNode(NodeEx node, Configuration config) {
|
||||
config.isSource(node.asNode()) and
|
||||
not fullBarrier(node, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) }
|
||||
|
||||
/** Provides the relevant barriers for a step from `node1` to `node2`. */
|
||||
pragma[inline]
|
||||
private predicate stepFilter(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
@@ -320,16 +333,14 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.asNode() = n and
|
||||
node2.isImplicitReadNode(n, false)
|
||||
node2.isImplicitReadNode(n, false) and
|
||||
not fullBarrier(node1, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -342,16 +353,14 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.isImplicitReadNode(n, true) and
|
||||
node2.asNode() = n
|
||||
node2.asNode() = n and
|
||||
not fullBarrier(node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -363,10 +372,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
@@ -380,16 +386,14 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
|
||||
private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) {
|
||||
read(node1.asNode(), c, node2.asNode())
|
||||
read(node1.asNode(), c, node2.asNode()) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
node2.isImplicitReadNode(n, true) and
|
||||
@@ -402,7 +406,8 @@ private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
read(_, tc.getContent(), _, config)
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -451,63 +456,59 @@ private module Stage1 {
|
||||
* argument in a call.
|
||||
*/
|
||||
predicate fwdFlow(NodeEx node, Cc cc, Configuration config) {
|
||||
not fullBarrier(node, config) and
|
||||
(
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config) and
|
||||
not outBarrier(mid, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config) and
|
||||
not inBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -547,7 +548,8 @@ private module Stage1 {
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
viableReturnPosOutEx(call, pos, out)
|
||||
viableReturnPosOutEx(call, pos, out) and
|
||||
not fullBarrier(out, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -773,6 +775,7 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
@@ -1019,12 +1022,14 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,9 +1147,8 @@ private module Stage2 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1159,9 +1163,8 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1171,10 +1174,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1230,6 +1231,11 @@ private module Stage2 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -1306,7 +1312,7 @@ private module Stage2 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -1341,9 +1347,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1353,9 +1358,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1365,9 +1369,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1707,12 +1710,14 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1837,9 +1842,8 @@ private module Stage3 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1854,9 +1858,8 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1866,10 +1869,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1925,6 +1926,11 @@ private module Stage3 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2001,7 +2007,7 @@ private module Stage3 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2036,9 +2042,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2048,9 +2053,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2060,9 +2064,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2473,12 +2476,14 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2603,9 +2608,8 @@ private module Stage4 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2620,9 +2624,8 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2632,10 +2635,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2691,6 +2692,11 @@ private module Stage4 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2767,7 +2773,7 @@ private module Stage4 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2802,9 +2808,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2814,9 +2819,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2826,9 +2830,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,19 @@ private import tainttracking1.TaintTrackingParameter::Private
|
||||
private import tainttracking1.TaintTrackingParameter::Public
|
||||
|
||||
module Consistency {
|
||||
private newtype TConsistencyConfiguration = MkConsistencyConfiguration()
|
||||
|
||||
/** A class for configuring the consistency queries. */
|
||||
class ConsistencyConfiguration extends TConsistencyConfiguration {
|
||||
string toString() { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */
|
||||
predicate postWithInFlowExclude(Node n) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */
|
||||
predicate argHasPostUpdateExclude(ArgumentNode n) { none() }
|
||||
}
|
||||
|
||||
private class RelevantNode extends Node {
|
||||
RelevantNode() {
|
||||
this instanceof ArgumentNode or
|
||||
@@ -164,7 +177,7 @@ module Consistency {
|
||||
|
||||
query predicate argHasPostUpdate(ArgumentNode n, string msg) {
|
||||
not hasPost(n) and
|
||||
not isImmutableOrUnobservable(n) and
|
||||
not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and
|
||||
msg = "ArgumentNode is missing PostUpdateNode."
|
||||
}
|
||||
|
||||
@@ -177,6 +190,7 @@ module Consistency {
|
||||
isPostUpdateNode(n) and
|
||||
not clearsContent(n, _) and
|
||||
simpleLocalFlowStep(_, n) and
|
||||
not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
|
||||
msg = "PostUpdateNode should not be the target of local flow."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ private import cpp
|
||||
private import DataFlowUtil
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import DataFlowDispatch
|
||||
private import DataFlowImplConsistency
|
||||
|
||||
/** Gets the callable in which this node occurs. */
|
||||
DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() }
|
||||
@@ -285,21 +286,18 @@ class Unit extends TUnit {
|
||||
string toString() { result = "unit" }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `n` does not require a `PostUpdateNode` as it either cannot be
|
||||
* modified or its modification cannot be observed, for example if it is a
|
||||
* freshly created object that is not saved in a variable.
|
||||
*
|
||||
* This predicate is only used for consistency checks.
|
||||
*/
|
||||
predicate isImmutableOrUnobservable(Node n) {
|
||||
// The rules for whether an IR argument gets a post-update node are too
|
||||
// complex to model here.
|
||||
any()
|
||||
}
|
||||
|
||||
/** Holds if `n` should be hidden from path explanations. */
|
||||
predicate nodeIsHidden(Node n) { n instanceof OperandNode and not n instanceof ArgumentNode }
|
||||
predicate nodeIsHidden(Node n) {
|
||||
n instanceof OperandNode and not n instanceof ArgumentNode
|
||||
or
|
||||
StoreNodeFlow::flowThrough(n, _) and
|
||||
not StoreNodeFlow::flowOutOf(n, _) and
|
||||
not StoreNodeFlow::flowInto(_, n)
|
||||
or
|
||||
ReadNodeFlow::flowThrough(n, _) and
|
||||
not ReadNodeFlow::flowOutOf(n, _) and
|
||||
not ReadNodeFlow::flowInto(_, n)
|
||||
}
|
||||
|
||||
class LambdaCallKind = Unit;
|
||||
|
||||
@@ -320,3 +318,11 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves
|
||||
* by default as a heuristic.
|
||||
*/
|
||||
predicate allowParameterReturnInSelf(ParameterNode p) { none() }
|
||||
|
||||
private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration {
|
||||
override predicate argHasPostUpdateExclude(ArgumentNode n) {
|
||||
// The rules for whether an IR argument gets a post-update node are too
|
||||
// complex to model here.
|
||||
any()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -806,7 +806,7 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
simpleOperandLocalFlowStep(nodeFrom.asInstruction(), nodeTo.asOperand())
|
||||
or
|
||||
// Flow into, through, and out of store nodes
|
||||
StoreNodeFlow::flowInto(nodeFrom, nodeTo)
|
||||
StoreNodeFlow::flowInto(nodeFrom.asInstruction(), nodeTo)
|
||||
or
|
||||
StoreNodeFlow::flowThrough(nodeFrom, nodeTo)
|
||||
or
|
||||
@@ -831,23 +831,19 @@ private predicate adjacentDefUseFlow(Node nodeFrom, Node nodeTo) {
|
||||
//Def-use flow
|
||||
Ssa::ssaFlow(nodeFrom, nodeTo)
|
||||
or
|
||||
exists(Instruction loadAddress | loadAddress = Ssa::getSourceAddressFromNode(nodeFrom) |
|
||||
// Use-use flow through reads
|
||||
exists(Node address |
|
||||
Ssa::addressFlowTC(address.asInstruction(), loadAddress) and
|
||||
Ssa::ssaFlow(address, nodeTo)
|
||||
)
|
||||
or
|
||||
// Use-use flow through stores.
|
||||
exists(Node store |
|
||||
Ssa::explicitWrite(_, store.asInstruction(), loadAddress) and
|
||||
Ssa::ssaFlow(store, nodeTo)
|
||||
)
|
||||
// Use-use flow through stores.
|
||||
exists(Instruction loadAddress, Node store |
|
||||
loadAddress = Ssa::getSourceAddressFromNode(nodeFrom) and
|
||||
Ssa::explicitWrite(_, store.asInstruction(), loadAddress) and
|
||||
Ssa::ssaFlow(store, nodeTo)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private module ReadNodeFlow {
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
module ReadNodeFlow {
|
||||
/** Holds if the read node `nodeTo` should receive flow from `nodeFrom`. */
|
||||
predicate flowInto(Node nodeFrom, ReadNode nodeTo) {
|
||||
nodeTo.isInitial() and
|
||||
@@ -867,7 +863,12 @@ private module ReadNodeFlow {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if the read node `nodeTo` should receive flow from the read node `nodeFrom`. */
|
||||
/**
|
||||
* Holds if the read node `nodeTo` should receive flow from the read node `nodeFrom`.
|
||||
*
|
||||
* This happens when `readFrom` is _not_ the source of a `readStep`, and `nodeTo` is
|
||||
* the `ReadNode` that represents an address that directly depends on `nodeFrom`.
|
||||
*/
|
||||
predicate flowThrough(ReadNode nodeFrom, ReadNode nodeTo) {
|
||||
not readStep(nodeFrom, _, _) and
|
||||
nodeFrom.getOuter() = nodeTo
|
||||
@@ -906,17 +907,25 @@ private module ReadNodeFlow {
|
||||
}
|
||||
}
|
||||
|
||||
private module StoreNodeFlow {
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
module StoreNodeFlow {
|
||||
/** Holds if the store node `nodeTo` should receive flow from `nodeFrom`. */
|
||||
predicate flowInto(Node nodeFrom, StoreNode nodeTo) {
|
||||
nodeTo.flowInto(Ssa::getDestinationAddress(nodeFrom.asInstruction()))
|
||||
predicate flowInto(Instruction instrFrom, StoreNode nodeTo) {
|
||||
nodeTo.flowInto(Ssa::getDestinationAddress(instrFrom))
|
||||
}
|
||||
|
||||
/** Holds if the store node `nodeTo` should receive flow from `nodeFom`. */
|
||||
predicate flowThrough(StoreNode nFrom, StoreNode nodeTo) {
|
||||
/**
|
||||
* Holds if the store node `nodeTo` should receive flow from `nodeFom`.
|
||||
*
|
||||
* This happens when `nodeFrom` is _not_ the source of a `storeStep`, and `nodeFrom` is
|
||||
* the `Storenode` that represents an address that directly depends on `nodeTo`.
|
||||
*/
|
||||
predicate flowThrough(StoreNode nodeFrom, StoreNode nodeTo) {
|
||||
// Flow through a post update node that doesn't need a store step.
|
||||
not storeStep(nFrom, _, _) and
|
||||
nodeTo.getOuter() = nFrom
|
||||
not storeStep(nodeFrom, _, _) and
|
||||
nodeTo.getOuter() = nodeFrom
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -634,3 +634,29 @@ class UncertainWriteDefinition extends WriteDefinition {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides a set of consistency queries. */
|
||||
module Consistency {
|
||||
abstract class RelevantDefinition extends Definition {
|
||||
abstract predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
);
|
||||
}
|
||||
|
||||
query predicate nonUniqueDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) {
|
||||
ssaDefReachesRead(v, def, bb, i) and
|
||||
not exists(unique(Definition def0 | ssaDefReachesRead(v, def0, bb, i)))
|
||||
}
|
||||
|
||||
query predicate readWithoutDef(SourceVariable v, BasicBlock bb, int i) {
|
||||
variableRead(bb, i, v, _) and
|
||||
not ssaDefReachesRead(v, _, bb, i)
|
||||
}
|
||||
|
||||
query predicate deadDef(RelevantDefinition def, SourceVariable v) {
|
||||
v = def.getSourceVariable() and
|
||||
not ssaDefReachesRead(_, def, _, _) and
|
||||
not phiHasInputFromBlock(_, def, _) and
|
||||
not uncertainWriteDefinitionInput(_, def)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,17 +244,6 @@ Instruction getDestinationAddress(Instruction instr) {
|
||||
]
|
||||
}
|
||||
|
||||
class ReferenceToInstruction extends CopyValueInstruction {
|
||||
ReferenceToInstruction() {
|
||||
this.getResultType() instanceof Cpp::ReferenceType and
|
||||
not this.getUnary().getResultType() instanceof Cpp::ReferenceType
|
||||
}
|
||||
|
||||
Instruction getSourceAddress() { result = getSourceAddressOperand().getDef() }
|
||||
|
||||
Operand getSourceAddressOperand() { result = this.getUnaryOperand() }
|
||||
}
|
||||
|
||||
/** Gets the source address of `instr` if it is an instruction that behaves like a `LoadInstruction`. */
|
||||
Instruction getSourceAddress(Instruction instr) { result = getSourceAddressOperand(instr).getDef() }
|
||||
|
||||
@@ -266,11 +255,7 @@ Operand getSourceAddressOperand(Instruction instr) {
|
||||
result =
|
||||
[
|
||||
instr.(LoadInstruction).getSourceAddressOperand(),
|
||||
instr.(ReadSideEffectInstruction).getArgumentOperand(),
|
||||
// `ReferenceToInstruction` is really more of an address-of operation,
|
||||
// but by including it in this list we break out of `flowOutOfAddressStep` at an
|
||||
// instruction that, at the source level, looks like a use of a variable.
|
||||
instr.(ReferenceToInstruction).getSourceAddressOperand()
|
||||
instr.(ReadSideEffectInstruction).getArgumentOperand()
|
||||
]
|
||||
}
|
||||
|
||||
@@ -295,10 +280,6 @@ Operand getSourceValueOperand(Instruction instr) {
|
||||
result = instr.(LoadInstruction).getSourceValueOperand()
|
||||
or
|
||||
result = instr.(ReadSideEffectInstruction).getSideEffectOperand()
|
||||
or
|
||||
// See the comment on the `ReferenceToInstruction` disjunct in `getSourceAddressOperand` for why
|
||||
// this case is included.
|
||||
result = instr.(ReferenceToInstruction).getSourceValueOperand()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -513,6 +494,64 @@ private module Cached {
|
||||
explicitWrite(false, storeNode.getStoreInstruction(), def)
|
||||
)
|
||||
or
|
||||
// The destination of a store operation has undergone lvalue-to-rvalue conversion and is now a
|
||||
// right-hand-side of a store operation.
|
||||
// Find the next use of the variable in that store operation, and recursively find the load of that
|
||||
// pointer. For example, consider this case:
|
||||
//
|
||||
// ```cpp
|
||||
// int x = source();
|
||||
// int* p = &x;
|
||||
// sink(*p);
|
||||
// ```
|
||||
//
|
||||
// if we want to find the load of the address of `x`, we see that the pointer is stored into `p`,
|
||||
// and we then need to recursively look for the load of `p`.
|
||||
exists(
|
||||
Def def, StoreInstruction store, IRBlock block1, int rnk1, Use use, IRBlock block2, int rnk2
|
||||
|
|
||||
store = def.getInstruction() and
|
||||
store.getSourceValueOperand() = operand and
|
||||
def.hasRankInBlock(block1, rnk1) and
|
||||
use.hasRankInBlock(block2, rnk2) and
|
||||
adjacentDefRead(_, block1, rnk1, block2, rnk2)
|
||||
|
|
||||
// The shared SSA library has determined that `use` is the next use of the operand
|
||||
// so we find the next load of that use (but only if there is no `PostUpdateNode`) we
|
||||
// need to flow into first.
|
||||
not StoreNodeFlow::flowInto(store, _) and
|
||||
flowOutOfAddressStep(use.getOperand(), nodeTo)
|
||||
or
|
||||
// It may also be the case that `store` gives rise to another store step. So let's make sure that
|
||||
// we also take those into account.
|
||||
StoreNodeFlow::flowInto(store, nodeTo)
|
||||
)
|
||||
or
|
||||
// As we find the next load of an address, we might come across another use of the same variable.
|
||||
// In that case, we recursively find the next use of _that_ operand, and continue searching for
|
||||
// the next load of that operand. For example, consider this case:
|
||||
//
|
||||
// ```cpp
|
||||
// int x = source();
|
||||
// use(&x);
|
||||
// int* p = &x;
|
||||
// sink(*p);
|
||||
// ```
|
||||
//
|
||||
// The next use of `x` after its definition is `use(&x)`, but there is a later load of the address
|
||||
// of `x` that we want to flow to. So we use the shared SSA library to find the next load.
|
||||
not operand = getSourceAddressOperand(_) and
|
||||
exists(Use use1, Use use2, IRBlock block1, int rnk1, IRBlock block2, int rnk2 |
|
||||
use1.getOperand() = operand and
|
||||
use1.hasRankInBlock(block1, rnk1) and
|
||||
// Don't flow to the next use if this use is part of a store operation that totally
|
||||
// overrides a variable.
|
||||
not explicitWrite(true, _, use1.getOperand().getDef()) and
|
||||
adjacentDefRead(_, block1, rnk1, block2, rnk2) and
|
||||
use2.hasRankInBlock(block2, rnk2) and
|
||||
flowOutOfAddressStep(use2.getOperand(), nodeTo)
|
||||
)
|
||||
or
|
||||
operand = getSourceAddressOperand(nodeTo.asInstruction())
|
||||
or
|
||||
exists(ReturnIndirectionInstruction ret |
|
||||
|
||||
@@ -20,6 +20,14 @@ private import internal.OperandInternal
|
||||
private class TStageOperand =
|
||||
TRegisterOperand or TNonSSAMemoryOperand or TPhiOperand or TChiOperand;
|
||||
|
||||
/**
|
||||
* A known location. Testing `loc instanceof KnownLocation` will account for non existing locations, as
|
||||
* opposed to testing `not loc isntanceof UnknownLocation`
|
||||
*/
|
||||
private class KnownLocation extends Language::Location {
|
||||
KnownLocation() { not this instanceof Language::UnknownLocation }
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand of an `Instruction`. The operand represents a use of the result of one instruction
|
||||
* (the defining instruction) in another instruction (the use instruction)
|
||||
@@ -45,8 +53,10 @@ class Operand extends TStageOperand {
|
||||
|
||||
/**
|
||||
* Gets the location of the source code for this operand.
|
||||
* By default this is where the operand is used, but some subclasses may override this
|
||||
* using `getAnyDef()` if it makes more sense.
|
||||
*/
|
||||
final Language::Location getLocation() { result = this.getUse().getLocation() }
|
||||
Language::Location getLocation() { result = this.getUse().getLocation() }
|
||||
|
||||
/**
|
||||
* Gets the function that contains this operand.
|
||||
@@ -269,6 +279,10 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
// most `RegisterOperands` have a more meaningful location at the definition
|
||||
// the only exception are specific cases of `ThisArgumentOperand`
|
||||
override Language::Location getLocation() { result = this.getAnyDef().getLocation() }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override Overlap getDefinitionOverlap() {
|
||||
@@ -401,11 +415,19 @@ class ArgumentOperand extends RegisterOperand {
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand representing the implicit 'this' argument to a member function
|
||||
* An operand representing the implicit `this` argument to a member function
|
||||
* call.
|
||||
*/
|
||||
class ThisArgumentOperand extends ArgumentOperand {
|
||||
override ThisArgumentOperandTag tag;
|
||||
|
||||
// in most cases the def location makes more sense, but in some corner cases it
|
||||
// has an unknown location: in those cases we fall back to the use location
|
||||
override Language::Location getLocation() {
|
||||
if this.getAnyDef().getLocation() instanceof KnownLocation
|
||||
then result = this.getAnyDef().getLocation()
|
||||
else result = this.getUse().getLocation()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,14 @@ private import internal.OperandInternal
|
||||
private class TStageOperand =
|
||||
TRegisterOperand or TNonSSAMemoryOperand or TPhiOperand or TChiOperand;
|
||||
|
||||
/**
|
||||
* A known location. Testing `loc instanceof KnownLocation` will account for non existing locations, as
|
||||
* opposed to testing `not loc isntanceof UnknownLocation`
|
||||
*/
|
||||
private class KnownLocation extends Language::Location {
|
||||
KnownLocation() { not this instanceof Language::UnknownLocation }
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand of an `Instruction`. The operand represents a use of the result of one instruction
|
||||
* (the defining instruction) in another instruction (the use instruction)
|
||||
@@ -45,8 +53,10 @@ class Operand extends TStageOperand {
|
||||
|
||||
/**
|
||||
* Gets the location of the source code for this operand.
|
||||
* By default this is where the operand is used, but some subclasses may override this
|
||||
* using `getAnyDef()` if it makes more sense.
|
||||
*/
|
||||
final Language::Location getLocation() { result = this.getUse().getLocation() }
|
||||
Language::Location getLocation() { result = this.getUse().getLocation() }
|
||||
|
||||
/**
|
||||
* Gets the function that contains this operand.
|
||||
@@ -269,6 +279,10 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
// most `RegisterOperands` have a more meaningful location at the definition
|
||||
// the only exception are specific cases of `ThisArgumentOperand`
|
||||
override Language::Location getLocation() { result = this.getAnyDef().getLocation() }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override Overlap getDefinitionOverlap() {
|
||||
@@ -401,11 +415,19 @@ class ArgumentOperand extends RegisterOperand {
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand representing the implicit 'this' argument to a member function
|
||||
* An operand representing the implicit `this` argument to a member function
|
||||
* call.
|
||||
*/
|
||||
class ThisArgumentOperand extends ArgumentOperand {
|
||||
override ThisArgumentOperandTag tag;
|
||||
|
||||
// in most cases the def location makes more sense, but in some corner cases it
|
||||
// has an unknown location: in those cases we fall back to the use location
|
||||
override Language::Location getLocation() {
|
||||
if this.getAnyDef().getLocation() instanceof KnownLocation
|
||||
then result = this.getAnyDef().getLocation()
|
||||
else result = this.getUse().getLocation()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,14 @@ private import internal.OperandInternal
|
||||
private class TStageOperand =
|
||||
TRegisterOperand or TNonSSAMemoryOperand or TPhiOperand or TChiOperand;
|
||||
|
||||
/**
|
||||
* A known location. Testing `loc instanceof KnownLocation` will account for non existing locations, as
|
||||
* opposed to testing `not loc isntanceof UnknownLocation`
|
||||
*/
|
||||
private class KnownLocation extends Language::Location {
|
||||
KnownLocation() { not this instanceof Language::UnknownLocation }
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand of an `Instruction`. The operand represents a use of the result of one instruction
|
||||
* (the defining instruction) in another instruction (the use instruction)
|
||||
@@ -45,8 +53,10 @@ class Operand extends TStageOperand {
|
||||
|
||||
/**
|
||||
* Gets the location of the source code for this operand.
|
||||
* By default this is where the operand is used, but some subclasses may override this
|
||||
* using `getAnyDef()` if it makes more sense.
|
||||
*/
|
||||
final Language::Location getLocation() { result = this.getUse().getLocation() }
|
||||
Language::Location getLocation() { result = this.getUse().getLocation() }
|
||||
|
||||
/**
|
||||
* Gets the function that contains this operand.
|
||||
@@ -269,6 +279,10 @@ class RegisterOperand extends NonPhiOperand, TRegisterOperand {
|
||||
|
||||
final override string toString() { result = tag.toString() }
|
||||
|
||||
// most `RegisterOperands` have a more meaningful location at the definition
|
||||
// the only exception are specific cases of `ThisArgumentOperand`
|
||||
override Language::Location getLocation() { result = this.getAnyDef().getLocation() }
|
||||
|
||||
final override Instruction getAnyDef() { result = defInstr }
|
||||
|
||||
final override Overlap getDefinitionOverlap() {
|
||||
@@ -401,11 +415,19 @@ class ArgumentOperand extends RegisterOperand {
|
||||
}
|
||||
|
||||
/**
|
||||
* An operand representing the implicit 'this' argument to a member function
|
||||
* An operand representing the implicit `this` argument to a member function
|
||||
* call.
|
||||
*/
|
||||
class ThisArgumentOperand extends ArgumentOperand {
|
||||
override ThisArgumentOperandTag tag;
|
||||
|
||||
// in most cases the def location makes more sense, but in some corner cases it
|
||||
// has an unknown location: in those cases we fall back to the use location
|
||||
override Language::Location getLocation() {
|
||||
if this.getAnyDef().getLocation() instanceof KnownLocation
|
||||
then result = this.getAnyDef().getLocation()
|
||||
else result = this.getUse().getLocation()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,6 +34,16 @@ private class IteratorByTraits extends Iterator {
|
||||
IteratorByTraits() { exists(IteratorTraits it | it.getIteratorType() = this) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The C++ standard includes an `std::iterator_traits` specialization for pointer types. When
|
||||
* this specialization is included in the database, a pointer type `T*` will be an instance
|
||||
* of the `IteratorByTraits` class. However, if the `T*` specialization is not in the database,
|
||||
* we need to explicitly include them with this class.
|
||||
*/
|
||||
private class IteratorByPointer extends Iterator instanceof PointerType {
|
||||
IteratorByPointer() { not this instanceof IteratorByTraits }
|
||||
}
|
||||
|
||||
/**
|
||||
* A type which has the typedefs expected for an iterator.
|
||||
*/
|
||||
|
||||
5
cpp/ql/src/CHANGELOG.md
Normal file
5
cpp/ql/src/CHANGELOG.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 0.0.4
|
||||
|
||||
### New Queries
|
||||
|
||||
* A new query `cpp/non-https-url` has been added for C/C++. The query flags uses of `http` URLs that might be better replaced with `https`.
|
||||
@@ -29,7 +29,7 @@ class SqliteFunctionCall extends FunctionCall {
|
||||
}
|
||||
|
||||
predicate sqlite_encryption_used() {
|
||||
any(StringLiteral l).getValue().toLowerCase().regexpMatch("pragma key.*") or
|
||||
any(StringLiteral l).getValue().toLowerCase().matches("pragma key%") or
|
||||
any(StringLiteral l).getValue().toLowerCase().matches("%attach%database%key%") or
|
||||
any(FunctionCall fc).getTarget().getName().matches("sqlite%\\_key\\_%")
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* @id cpp/non-https-url
|
||||
* @tags security
|
||||
* external/cwe/cwe-319
|
||||
* external/cwe/cwe-345
|
||||
*/
|
||||
|
||||
import cpp
|
||||
@@ -61,7 +62,11 @@ class HttpStringToUrlOpenConfig extends TaintTracking::Configuration {
|
||||
// accessed as a URL, for example using it in a network access. Some
|
||||
// URLs are only ever displayed or used for data processing.
|
||||
exists(FunctionCall fc |
|
||||
fc.getTarget().hasGlobalOrStdName(["system", "gethostbyname", "getaddrinfo"]) and
|
||||
fc.getTarget()
|
||||
.hasGlobalOrStdName([
|
||||
"system", "gethostbyname", "gethostbyname2", "gethostbyname_r", "getaddrinfo",
|
||||
"X509_load_http", "X509_CRL_load_http"
|
||||
]) and
|
||||
sink.asExpr() = fc.getArgument(0)
|
||||
or
|
||||
fc.getTarget().hasGlobalOrStdName(["send", "URLDownloadToFile", "URLDownloadToCacheFile"]) and
|
||||
|
||||
5
cpp/ql/src/change-notes/released/0.0.4.md
Normal file
5
cpp/ql/src/change-notes/released/0.0.4.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 0.0.4
|
||||
|
||||
### New Queries
|
||||
|
||||
* A new query `cpp/non-https-url` has been added for C/C++. The query flags uses of `http` URLs that might be better replaced with `https`.
|
||||
2
cpp/ql/src/codeql-pack.release.yml
Normal file
2
cpp/ql/src/codeql-pack.release.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.0.4
|
||||
@@ -1,5 +1,6 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 0.0.2
|
||||
version: 0.0.4
|
||||
groups: cpp
|
||||
dependencies:
|
||||
codeql/cpp-all: "*"
|
||||
codeql/suite-helpers: "*"
|
||||
|
||||
@@ -4,8 +4,8 @@ using SinkFunction = void (*)(int);
|
||||
|
||||
void notSink(int notSinkParam);
|
||||
|
||||
void callsSink(int sinkParam) { // $ ir-path=31:28 ir-path=32:31 ir-path=34:22
|
||||
sink(sinkParam); // $ ir-sink=31:28 ir-sink=32:31 ir-sink=34:22 ast=31:28 ast=32:31 ast=34:22 MISSING: ast,ir=28
|
||||
void callsSink(int sinkParam) { // $ ir-path=31:23 ir-path=32:26 ir-path=34:17
|
||||
sink(sinkParam); // $ ast=31:28 ast=32:31 ast=34:22 ir-sink
|
||||
}
|
||||
|
||||
struct {
|
||||
@@ -25,7 +25,7 @@ void assignGlobals() {
|
||||
};
|
||||
|
||||
void testStruct() {
|
||||
globalStruct.sinkPtr(atoi(getenv("TAINTED"))); // $ ir MISSING: ast
|
||||
globalStruct.sinkPtr(atoi(getenv("TAINTED"))); // $ MISSING: ir-path,ast
|
||||
globalStruct.notSinkPtr(atoi(getenv("TAINTED"))); // clean
|
||||
|
||||
globalUnion.sinkPtr(atoi(getenv("TAINTED"))); // $ ast ir-path
|
||||
@@ -48,8 +48,8 @@ class D2 : public D1 {
|
||||
|
||||
class D3 : public D2 {
|
||||
public:
|
||||
void f(const char* p) override { // $ ir-path=58:10 ir-path=60:17 ir-path=61:28 ir-path=62:29 ir-path=63:33 ir-path=73:30
|
||||
sink(p); // $ ir-sink=58:10 ir-sink=60:17 ir-sink=61:28 ir-sink=62:29 ir-sink=63:33 ast=58:10 ast=60:17 ast=61:28 ast=62:29 ast=63:33 SPURIOUS: ast=73:30 ir-sink=73:30
|
||||
void f(const char* p) override { // $ ir-path=58:10 ir-path=60:17 ir-path=61:28 ir-path=62:29 ir-path=63:33 SPURIOUS: ir-path=73:30
|
||||
sink(p); // $ ast=58:10 ast=60:17 ast=61:28 ast=62:29 ast=63:33 ir-sink SPURIOUS: ast=73:30
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -23,11 +23,10 @@ class SourceConfiguration extends TaintedWithPath::TaintTrackingConfiguration {
|
||||
override predicate isSink(Element e) { isSinkArgument(e) }
|
||||
}
|
||||
|
||||
predicate irTaint(Element source, Element sink, string tag) {
|
||||
exists(TaintedWithPath::PathNode sinkNode, TaintedWithPath::PathNode predNode |
|
||||
predicate irTaint(Element source, TaintedWithPath::PathNode predNode, string tag) {
|
||||
exists(TaintedWithPath::PathNode sinkNode |
|
||||
TaintedWithPath::taintedWithPath(source, _, _, sinkNode) and
|
||||
predNode = getAPredecessor*(sinkNode) and
|
||||
sink = getElementFromPathNode(predNode) and
|
||||
// Make sure the path is actually reachable from this predecessor.
|
||||
// Otherwise, we could pick `predNode` to be b when `source` is
|
||||
// `source1` in this dataflow graph:
|
||||
@@ -35,7 +34,7 @@ predicate irTaint(Element source, Element sink, string tag) {
|
||||
// ^
|
||||
// source2 ---> b --/
|
||||
source = getElementFromPathNode(getAPredecessor*(predNode)) and
|
||||
if sinkNode = predNode then tag = "ir-sink" else tag = "ir-path"
|
||||
if predNode = sinkNode then tag = "ir-sink" else tag = "ir-path"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -45,21 +44,25 @@ class IRDefaultTaintTrackingTest extends InlineExpectationsTest {
|
||||
override string getARelevantTag() { result = ["ir-path", "ir-sink"] }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(Element source, Element tainted, int n |
|
||||
irTaint(source, tainted, tag) and
|
||||
n = strictcount(Element otherSource | irTaint(otherSource, tainted, _)) and
|
||||
(
|
||||
n = 1 and value = ""
|
||||
or
|
||||
// If there is more than one source for this sink
|
||||
// we specify the source location explicitly.
|
||||
n > 1 and
|
||||
exists(Element source, Element elem, TaintedWithPath::PathNode node, int n |
|
||||
irTaint(source, node, tag) and
|
||||
elem = getElementFromPathNode(node) and
|
||||
n = count(int startline | getAPredecessor(node).hasLocationInfo(_, startline, _, _, _)) and
|
||||
location = elem.getLocation() and
|
||||
element = elem.toString()
|
||||
|
|
||||
// Zero predecessors means it's a source, and 1 predecessor means it has a unique predecessor.
|
||||
// In either of these cases we leave out the location.
|
||||
n = [0, 1] and value = ""
|
||||
or
|
||||
// If there is more than one predecessor for this node
|
||||
// we specify the source location explicitly.
|
||||
n > 1 and
|
||||
exists(TaintedWithPath::PathNode pred | pred = getAPredecessor(node) |
|
||||
value =
|
||||
source.getLocation().getStartLine().toString() + ":" +
|
||||
source.getLocation().getStartColumn()
|
||||
) and
|
||||
location = tainted.getLocation() and
|
||||
element = tainted.toString()
|
||||
getElementFromPathNode(pred).getLocation().getStartLine().toString() + ":" +
|
||||
getElementFromPathNode(pred).getLocation().getStartColumn()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ struct S {
|
||||
}
|
||||
};
|
||||
|
||||
void calls_sink_with_argv(const char* a) { // $ ir-path=96:26 ir-path=98:18
|
||||
sink(a); // $ ast=96:26 ast=98:18 ir-sink=96:26 ir-sink=98:18
|
||||
void calls_sink_with_argv(const char* a) { // $ ir-path=96:26 ir-path=102:26
|
||||
sink(a); // $ ast=96:26 ast=98:18 ir-sink
|
||||
}
|
||||
|
||||
extern int i;
|
||||
@@ -27,7 +27,7 @@ public:
|
||||
class DerivedCallsSink : public BaseWithPureVirtual {
|
||||
public:
|
||||
void f(const char* p) override { // $ ir-path
|
||||
sink(p); // $ ir-sink ast=108:10 SPURIOUS: ast=111:10
|
||||
sink(p); // $ ast=108:10 ir-sink SPURIOUS: ast=111:10
|
||||
}
|
||||
};
|
||||
|
||||
@@ -49,8 +49,8 @@ public:
|
||||
};
|
||||
|
||||
class DerivesMultiple : public DerivedCallsSinkDiamond1, public DerivedDoesNotCallSinkDiamond2 {
|
||||
void f(const char* p) override { // $ ir-path
|
||||
DerivedCallsSinkDiamond1::f(p);
|
||||
void f(const char* p) override { // $ ir-path=53:37 ir-path=115:11
|
||||
DerivedCallsSinkDiamond1::f(p); // $ ir-path
|
||||
}
|
||||
};
|
||||
|
||||
@@ -58,7 +58,7 @@ template<typename T>
|
||||
class CRTP {
|
||||
public:
|
||||
void f(const char* p) { // $ ir-path
|
||||
static_cast<T*>(this)->g(p);
|
||||
static_cast<T*>(this)->g(p); // $ ir-path
|
||||
}
|
||||
};
|
||||
|
||||
@@ -79,7 +79,7 @@ class Derived2 : public Derived1 {
|
||||
class Derived3 : public Derived2 {
|
||||
public:
|
||||
void f(const char* p) override { // $ ir-path=124:19 ir-path=126:43 ir-path=128:44
|
||||
sink(p); // $ ast,ir-sink=124:19 ast,ir-sink=126:43 ast,ir-sink=128:44
|
||||
sink(p); // $ ast=124:19 ast=126:43 ast=128:44 ir-sink
|
||||
}
|
||||
};
|
||||
|
||||
@@ -97,11 +97,11 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
char*** p = &argv; // $ ast,ir-path
|
||||
|
||||
sink(*p[0]); // $ ast,ir-sink
|
||||
sink(*p[0]); // $ ast ir-sink=96:26 ir-sink=98:18
|
||||
|
||||
calls_sink_with_argv(*p[i]); // $ MISSING: ast,ir-path
|
||||
calls_sink_with_argv(*p[i]); // $ ir-path=96:26 ir-path=98:18 MISSING:ast
|
||||
|
||||
sink(*(argv + 1)); // $ ast,ir-path ir-sink
|
||||
sink(*(argv + 1)); // $ ast ir-path ir-sink
|
||||
|
||||
BaseWithPureVirtual* b = new DerivedCallsSink;
|
||||
|
||||
|
||||
@@ -190,9 +190,9 @@ void test_pointers1()
|
||||
sink(ptr1); // $ ast MISSING: ir
|
||||
sink(ptr2); // $ SPURIOUS: ast
|
||||
sink(*ptr2); // $ ast MISSING: ir
|
||||
sink(ptr3); // $ ast MISSING: ir
|
||||
sink(ptr4); // $ SPURIOUS: ast
|
||||
sink(*ptr4); // $ ast MISSING: ir
|
||||
sink(ptr3); // $ ast,ir
|
||||
sink(ptr4); // $ SPURIOUS: ast,ir
|
||||
sink(*ptr4); // $ ast,ir
|
||||
}
|
||||
|
||||
void test_pointers2()
|
||||
|
||||
@@ -35,17 +35,17 @@ postWithInFlow
|
||||
| BarrierGuard.cpp:60:3:60:4 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| BarrierGuard.cpp:60:7:60:7 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:8:20:8:29 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:22:3:22:6 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:22:8:22:20 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:22:8:22:20 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:22:9:22:20 | sourceArray1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:26:8:26:24 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:26:8:26:24 | sourceStruct1_ptr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:26:27:26:34 | sourceStruct1_ptr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:26:8:26:24 | sourceStruct1_ptr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:28:3:28:19 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:28:22:28:23 | m1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:30:8:30:24 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:30:8:30:24 | sourceStruct1_ptr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:30:27:30:34 | sourceStruct1_ptr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:30:8:30:24 | sourceStruct1_ptr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:34:19:34:41 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:34:19:34:41 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| clang.cpp:39:16:39:21 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -77,55 +77,55 @@ postWithInFlow
|
||||
| dispatch.cpp:29:29:29:34 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:31:8:31:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:31:8:31:13 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:31:16:31:24 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:31:8:31:13 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:32:8:32:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:32:8:32:13 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:32:16:32:24 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:32:8:32:13 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:33:3:33:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:33:3:33:8 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:33:11:33:16 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:33:3:33:8 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:35:8:35:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:35:8:35:13 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:35:16:35:25 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:35:8:35:13 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:36:8:36:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:36:8:36:13 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:36:16:36:25 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:36:8:36:13 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:37:3:37:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:37:3:37:8 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:37:11:37:17 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:37:3:37:8 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:39:8:39:13 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:39:8:39:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:39:8:39:13 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:39:15:39:23 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:39:8:39:13 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:40:8:40:13 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:40:8:40:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:40:8:40:13 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:40:15:40:23 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:40:8:40:13 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:41:3:41:8 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:41:3:41:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:41:3:41:8 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:41:10:41:15 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:41:3:41:8 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:43:8:43:13 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:43:8:43:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:43:8:43:13 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:43:15:43:24 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:43:8:43:13 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:44:8:44:13 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:44:8:44:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:44:8:44:13 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:44:15:44:24 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:44:8:44:13 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:45:3:45:8 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:45:3:45:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:45:3:45:8 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:45:10:45:16 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:45:3:45:8 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:51:3:51:22 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:55:8:55:19 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:55:8:55:19 | globalBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:55:22:55:30 | globalBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:55:8:55:19 | globalBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:56:8:56:19 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:56:8:56:19 | globalMiddle [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:56:22:56:30 | globalMiddle [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:56:8:56:19 | globalMiddle [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:58:8:58:23 | call to readGlobalBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:58:8:58:23 | call to readGlobalBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:58:28:58:36 | call to readGlobalBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:60:3:60:14 | globalBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:60:18:60:29 | Call [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:60:18:60:29 | new [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -140,34 +140,34 @@ postWithInFlow
|
||||
| dispatch.cpp:65:10:65:21 | new [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:69:3:69:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:69:3:69:5 | top [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:69:8:69:13 | top [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:69:3:69:5 | top [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:73:3:73:5 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:73:3:73:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:73:3:73:5 | top [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:73:7:73:12 | top [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:77:3:77:19 | call to allocateBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:73:3:73:5 | top [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:77:21:77:34 | call to allocateBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:77:21:77:34 | call to allocateBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:78:3:78:21 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:78:23:78:39 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:78:23:78:39 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:78:23:78:39 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:78:24:78:37 | call to allocateBottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:80:8:80:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:81:3:81:3 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:81:3:81:3 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:81:6:81:11 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:81:3:81:3 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:85:3:85:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:3:89:10 | bottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:3:89:10 | call to identity [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:3:89:10 | call to identity [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:12:89:17 | (Middle *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:12:89:17 | (Top *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:12:89:17 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:12:89:17 | bottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:21:89:26 | call to identity [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:89:12:89:17 | bottom [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:90:3:90:10 | call to identity [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:90:3:90:10 | call to identity [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:90:3:90:10 | top [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:90:12:90:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:90:12:90:14 | top [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:90:18:90:23 | call to identity [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:90:12:90:14 | top [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:100:3:100:18 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:105:5:105:17 | maybeCallSink [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:113:30:113:38 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -176,11 +176,11 @@ postWithInFlow
|
||||
| dispatch.cpp:127:31:127:36 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:129:10:129:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:129:10:129:15 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:129:18:129:25 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:129:10:129:15 | topPtr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:130:10:130:15 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:130:10:130:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:130:10:130:15 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:130:17:130:24 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:130:10:130:15 | topRef [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:148:3:148:3 | u [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:148:5:148:5 | f [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| dispatch.cpp:168:3:168:4 | u2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -191,10 +191,10 @@ postWithInFlow
|
||||
| example.c:24:9:24:9 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:24:20:24:20 | y [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:26:9:26:9 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:26:13:26:16 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:26:18:26:24 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:26:18:26:24 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:26:19:26:24 | coords [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:28:2:28:12 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:28:14:28:25 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:28:14:28:25 | (void *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:28:22:28:25 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:28:23:28:25 | pos [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -227,23 +227,23 @@ postWithInFlow
|
||||
| lambdas.cpp:43:3:43:3 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:43:3:43:3 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:43:3:43:3 | c [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:3:45:3 | t [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:3:45:3 | u [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:3:45:3 | w [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:4:45:4 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:4:45:4 | t [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:4:45:4 | t [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:7:45:7 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:7:45:7 | u [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:7:45:7 | u [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:10:45:10 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:10:45:10 | w [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:45:10:45:10 | w [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:11:5:11:7 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:11:5:11:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:11:5:11:7 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:16:5:16:10 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:16:12:16:14 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:16:12:16:14 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:16:12:16:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:16:12:16:14 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:16:12:16:14 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:20:5:20:7 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:20:5:20:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:20:5:20:7 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -259,11 +259,11 @@ postWithInFlow
|
||||
| ref.cpp:31:7:31:9 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:31:7:31:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:31:7:31:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:37:7:37:19 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:37:21:37:23 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:37:21:37:23 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:37:21:37:23 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:37:21:37:23 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:37:21:37:23 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:39:7:39:9 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:39:7:39:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:39:7:39:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -276,26 +276,26 @@ postWithInFlow
|
||||
| ref.cpp:48:7:48:9 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:48:7:48:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:48:7:48:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:55:5:55:17 | x1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:55:19:55:20 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:55:19:55:20 | x1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:58:5:58:13 | x2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:55:19:55:20 | x1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:58:15:58:16 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:58:15:58:16 | x2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:61:5:61:24 | x3 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:58:15:58:16 | x2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:61:26:61:27 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:61:26:61:27 | x3 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:64:5:64:13 | x4 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:61:26:61:27 | x3 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:64:15:64:16 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:64:15:64:16 | x4 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:64:15:64:16 | x4 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:75:5:75:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:75:5:75:7 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:75:9:75:11 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:79:5:79:10 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:79:12:79:14 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:79:12:79:14 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:79:12:79:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:79:12:79:14 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:79:12:79:14 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:83:5:83:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:83:5:83:7 | lhs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:83:9:83:11 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -311,11 +311,11 @@ postWithInFlow
|
||||
| ref.cpp:96:7:96:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:96:7:96:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:96:11:96:13 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:102:7:102:19 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:102:21:102:23 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:102:21:102:23 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:102:21:102:23 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:102:21:102:23 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:102:21:102:23 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:104:7:104:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:104:7:104:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:104:11:104:13 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -328,18 +328,18 @@ postWithInFlow
|
||||
| ref.cpp:115:7:115:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:115:7:115:9 | out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:115:11:115:13 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:122:5:122:17 | x1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:122:19:122:20 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:122:19:122:20 | x1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:125:5:125:13 | x2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:122:19:122:20 | x1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:125:15:125:16 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:125:15:125:16 | x2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:128:5:128:24 | x3 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:125:15:125:16 | x2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:128:26:128:27 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:128:26:128:27 | x3 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:131:5:131:13 | x4 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:128:26:128:27 | x3 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:131:15:131:16 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:131:15:131:16 | x4 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ref.cpp:131:15:131:16 | x4 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:6:7:6:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:8:3:8:4 | t2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:12:5:12:6 | t2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -520,40 +520,40 @@ postWithInFlow
|
||||
| test.cpp:374:5:374:20 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:374:5:374:20 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:383:7:383:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:384:3:384:8 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:384:10:384:13 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:384:10:384:13 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:384:10:384:13 | (void *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:384:11:384:13 | tmp [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:389:7:389:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:390:8:390:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:391:3:391:8 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:391:10:391:13 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:391:10:391:13 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:391:10:391:13 | (void *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:391:11:391:13 | tmp [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:400:3:400:8 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:400:10:400:13 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:400:10:400:13 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:400:10:400:13 | (void *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:400:11:400:13 | tmp [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:406:8:406:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:407:3:407:8 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:407:10:407:13 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:407:10:407:13 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:407:10:407:13 | (void *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:407:11:407:13 | tmp [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:417:3:417:14 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:417:16:417:20 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:417:16:417:20 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:423:3:423:18 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:417:16:417:20 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:423:20:423:25 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:423:20:423:25 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:423:21:423:25 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:429:3:429:18 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:429:20:429:24 | array to pointer conversion [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:429:20:429:24 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:436:3:436:16 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:429:20:429:24 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:436:18:436:23 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:436:18:436:23 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:436:19:436:23 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:442:3:442:16 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:442:18:442:22 | array to pointer conversion [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:442:18:442:22 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:442:18:442:22 | local [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:453:7:453:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:456:7:456:9 | tmp [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:458:7:458:9 | tmp [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -561,12 +561,12 @@ postWithInFlow
|
||||
| test.cpp:465:4:465:4 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:465:4:465:4 | p [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:469:7:469:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:470:3:470:19 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:470:21:470:22 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:470:21:470:22 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:470:22:470:22 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:481:3:481:19 | content [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:481:21:481:21 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:481:21:481:30 | (void *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:481:21:481:30 | content [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:481:24:481:30 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:481:24:481:30 | content [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| test.cpp:482:8:482:16 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
| example.c:15:37:15:37 | b | example.c:15:37:15:37 | b |
|
||||
| example.c:15:37:15:37 | b | example.c:19:6:19:6 | b |
|
||||
| example.c:15:44:15:46 | pos | example.c:24:24:24:26 | pos |
|
||||
| example.c:15:44:15:46 | pos | example.c:28:23:28:25 | pos |
|
||||
@@ -70,8 +71,10 @@
|
||||
| test.cpp:391:11:391:13 | tmp | test.cpp:391:10:391:13 | & ... |
|
||||
| test.cpp:391:17:391:23 | source1 | test.cpp:391:10:391:13 | ref arg & ... |
|
||||
| test.cpp:391:17:391:23 | source1 | test.cpp:391:16:391:23 | & ... |
|
||||
| test.cpp:480:67:480:67 | s | test.cpp:480:67:480:67 | s |
|
||||
| test.cpp:480:67:480:67 | s | test.cpp:481:21:481:21 | s |
|
||||
| test.cpp:480:67:480:67 | s | test.cpp:482:20:482:20 | s |
|
||||
| test.cpp:481:21:481:21 | s [post update] | test.cpp:480:67:480:67 | s |
|
||||
| test.cpp:481:21:481:21 | s [post update] | test.cpp:482:20:482:20 | s |
|
||||
| test.cpp:481:24:481:30 | ref arg content | test.cpp:482:23:482:29 | content |
|
||||
| test.cpp:482:23:482:29 | content | test.cpp:483:9:483:17 | p_content |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,28 +1,28 @@
|
||||
| A.cpp:25:13:25:13 | c | AST only |
|
||||
| A.cpp:27:28:27:28 | c | AST only |
|
||||
| A.cpp:31:14:31:21 | new | IR only |
|
||||
| A.cpp:40:8:40:13 | 0 | IR only |
|
||||
| A.cpp:41:8:41:13 | new | IR only |
|
||||
| A.cpp:40:15:40:21 | 0 | IR only |
|
||||
| A.cpp:41:15:41:21 | new | IR only |
|
||||
| A.cpp:41:15:41:21 | new | IR only |
|
||||
| A.cpp:47:12:47:18 | new | IR only |
|
||||
| A.cpp:54:12:54:18 | new | IR only |
|
||||
| A.cpp:55:8:55:10 | new | IR only |
|
||||
| A.cpp:55:12:55:19 | new | IR only |
|
||||
| A.cpp:55:12:55:19 | new | IR only |
|
||||
| A.cpp:57:11:57:24 | new | IR only |
|
||||
| A.cpp:57:11:57:24 | new | IR only |
|
||||
| A.cpp:57:17:57:23 | new | IR only |
|
||||
| A.cpp:57:28:57:30 | new | IR only |
|
||||
| A.cpp:57:17:57:23 | new | IR only |
|
||||
| A.cpp:62:13:62:19 | new | IR only |
|
||||
| A.cpp:64:10:64:15 | new | IR only |
|
||||
| A.cpp:64:21:64:28 | new | IR only |
|
||||
| A.cpp:64:21:64:28 | new | IR only |
|
||||
| A.cpp:71:13:71:19 | new | IR only |
|
||||
| A.cpp:73:10:73:19 | new | IR only |
|
||||
| A.cpp:73:25:73:32 | new | IR only |
|
||||
| A.cpp:73:25:73:32 | new | IR only |
|
||||
| A.cpp:89:15:89:21 | new | IR only |
|
||||
| A.cpp:99:14:99:21 | new | IR only |
|
||||
| A.cpp:100:9:100:9 | a | AST only |
|
||||
| A.cpp:116:12:116:19 | new | IR only |
|
||||
| A.cpp:126:8:126:10 | new | IR only |
|
||||
| A.cpp:126:12:126:18 | new | IR only |
|
||||
| A.cpp:126:12:126:18 | new | IR only |
|
||||
| A.cpp:130:12:130:18 | new | IR only |
|
||||
| A.cpp:142:10:142:10 | c | AST only |
|
||||
@@ -33,57 +33,57 @@
|
||||
| A.cpp:151:12:151:24 | new | IR only |
|
||||
| A.cpp:159:12:159:18 | new | IR only |
|
||||
| A.cpp:160:18:160:60 | new | IR only |
|
||||
| A.cpp:160:18:160:60 | new | IR only |
|
||||
| A.cpp:160:32:160:59 | 0 | IR only |
|
||||
| A.cpp:160:32:160:59 | 0 | IR only |
|
||||
| A.cpp:160:32:160:59 | new | IR only |
|
||||
| A.cpp:161:18:161:40 | 0 | IR only |
|
||||
| A.cpp:160:32:160:59 | new | IR only |
|
||||
| A.cpp:160:43:160:49 | 0 | IR only |
|
||||
| A.cpp:160:52:160:58 | 0 | IR only |
|
||||
| A.cpp:161:18:161:40 | new | IR only |
|
||||
| A.cpp:162:18:162:40 | 0 | IR only |
|
||||
| A.cpp:161:29:161:35 | 0 | IR only |
|
||||
| A.cpp:162:18:162:40 | new | IR only |
|
||||
| A.cpp:162:29:162:35 | 0 | IR only |
|
||||
| A.cpp:183:7:183:10 | head | AST only |
|
||||
| A.cpp:184:13:184:16 | next | AST only |
|
||||
| B.cpp:7:16:7:35 | 0 | IR only |
|
||||
| B.cpp:7:16:7:35 | new | IR only |
|
||||
| B.cpp:7:28:7:34 | 0 | IR only |
|
||||
| B.cpp:8:16:8:27 | new | IR only |
|
||||
| B.cpp:16:16:16:38 | 0 | IR only |
|
||||
| B.cpp:16:16:16:38 | new | IR only |
|
||||
| B.cpp:16:28:16:34 | 0 | IR only |
|
||||
| B.cpp:17:16:17:27 | new | IR only |
|
||||
| B.cpp:35:13:35:17 | elem1 | AST only |
|
||||
| B.cpp:36:13:36:17 | elem2 | AST only |
|
||||
| B.cpp:46:13:46:16 | box1 | AST only |
|
||||
| C.cpp:18:12:18:18 | new | IR only |
|
||||
| C.cpp:24:11:24:12 | s3 | AST only |
|
||||
| C.cpp:30:5:30:8 | s2 | IR only |
|
||||
| C.cpp:30:10:30:11 | s2 | IR only |
|
||||
| C.cpp:30:10:30:11 | this | IR only |
|
||||
| C.cpp:32:5:32:8 | s4 | IR only |
|
||||
| C.cpp:32:10:32:11 | s4 | IR only |
|
||||
| D.cpp:9:21:9:24 | elem | AST only |
|
||||
| D.cpp:11:29:11:32 | elem | AST only |
|
||||
| D.cpp:16:21:16:23 | box | AST only |
|
||||
| D.cpp:18:29:18:31 | box | AST only |
|
||||
| D.cpp:29:15:29:41 | new | IR only |
|
||||
| D.cpp:29:15:29:41 | new | IR only |
|
||||
| D.cpp:29:24:29:40 | 0 | IR only |
|
||||
| D.cpp:29:24:29:40 | new | IR only |
|
||||
| D.cpp:29:24:29:40 | new | IR only |
|
||||
| D.cpp:29:33:29:39 | 0 | IR only |
|
||||
| D.cpp:30:13:30:16 | elem | AST only |
|
||||
| D.cpp:36:15:36:41 | new | IR only |
|
||||
| D.cpp:36:15:36:41 | new | IR only |
|
||||
| D.cpp:36:24:36:40 | 0 | IR only |
|
||||
| D.cpp:36:24:36:40 | new | IR only |
|
||||
| D.cpp:36:24:36:40 | new | IR only |
|
||||
| D.cpp:36:33:36:39 | 0 | IR only |
|
||||
| D.cpp:43:15:43:41 | new | IR only |
|
||||
| D.cpp:43:15:43:41 | new | IR only |
|
||||
| D.cpp:43:24:43:40 | 0 | IR only |
|
||||
| D.cpp:43:24:43:40 | new | IR only |
|
||||
| D.cpp:43:24:43:40 | new | IR only |
|
||||
| D.cpp:43:33:43:39 | 0 | IR only |
|
||||
| D.cpp:44:19:44:22 | elem | AST only |
|
||||
| D.cpp:50:15:50:41 | new | IR only |
|
||||
| D.cpp:50:15:50:41 | new | IR only |
|
||||
| D.cpp:50:24:50:40 | 0 | IR only |
|
||||
| D.cpp:50:24:50:40 | new | IR only |
|
||||
| D.cpp:50:24:50:40 | new | IR only |
|
||||
| D.cpp:50:33:50:39 | 0 | IR only |
|
||||
| D.cpp:57:5:57:12 | boxfield | AST only |
|
||||
| D.cpp:57:16:57:42 | new | IR only |
|
||||
| D.cpp:57:16:57:42 | new | IR only |
|
||||
| D.cpp:57:25:57:41 | 0 | IR only |
|
||||
| D.cpp:57:25:57:41 | new | IR only |
|
||||
| D.cpp:57:25:57:41 | new | IR only |
|
||||
| D.cpp:57:34:57:40 | 0 | IR only |
|
||||
| D.cpp:58:20:58:23 | elem | AST only |
|
||||
| aliasing.cpp:9:6:9:7 | m1 | AST only |
|
||||
| aliasing.cpp:13:5:13:6 | m1 | AST only |
|
||||
@@ -100,13 +100,13 @@
|
||||
| aliasing.cpp:98:5:98:6 | m1 | AST only |
|
||||
| aliasing.cpp:106:3:106:5 | * ... | AST only |
|
||||
| arrays.cpp:6:3:6:8 | access to array | AST only |
|
||||
| arrays.cpp:7:3:7:6 | access to array | IR only |
|
||||
| arrays.cpp:8:3:8:6 | access to array | IR only |
|
||||
| arrays.cpp:9:3:9:6 | * ... | IR only |
|
||||
| arrays.cpp:10:3:10:6 | * ... | IR only |
|
||||
| arrays.cpp:7:8:7:13 | access to array | IR only |
|
||||
| arrays.cpp:8:8:8:13 | access to array | IR only |
|
||||
| arrays.cpp:9:8:9:11 | * ... | IR only |
|
||||
| arrays.cpp:10:8:10:15 | * ... | IR only |
|
||||
| arrays.cpp:15:3:15:10 | * ... | AST only |
|
||||
| arrays.cpp:16:3:16:6 | access to array | IR only |
|
||||
| arrays.cpp:17:3:17:6 | access to array | IR only |
|
||||
| arrays.cpp:16:8:16:13 | access to array | IR only |
|
||||
| arrays.cpp:17:8:17:13 | access to array | IR only |
|
||||
| arrays.cpp:36:19:36:22 | data | AST only |
|
||||
| arrays.cpp:42:22:42:25 | data | AST only |
|
||||
| arrays.cpp:48:22:48:25 | data | AST only |
|
||||
|
||||
@@ -10,29 +10,35 @@ edges
|
||||
| A.cpp:31:20:31:20 | c | A.cpp:23:10:23:10 | c |
|
||||
| A.cpp:31:20:31:20 | c | A.cpp:31:14:31:21 | call to B [c] |
|
||||
| A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... |
|
||||
| A.cpp:43:10:43:12 | & ... | A.cpp:173:26:173:26 | o |
|
||||
| A.cpp:47:12:47:18 | new | A.cpp:48:20:48:20 | c |
|
||||
| A.cpp:48:12:48:18 | call to make [c] | A.cpp:49:10:49:10 | b [c] |
|
||||
| A.cpp:48:20:48:20 | c | A.cpp:29:23:29:23 | c |
|
||||
| A.cpp:48:20:48:20 | c | A.cpp:48:12:48:18 | call to make [c] |
|
||||
| A.cpp:49:10:49:10 | b [c] | A.cpp:49:13:49:13 | c |
|
||||
| A.cpp:49:13:49:13 | c | A.cpp:173:26:173:26 | o |
|
||||
| A.cpp:55:5:55:5 | ref arg b [c] | A.cpp:56:10:56:10 | b [c] |
|
||||
| A.cpp:55:12:55:19 | new | A.cpp:27:17:27:17 | c |
|
||||
| A.cpp:55:12:55:19 | new | A.cpp:55:5:55:5 | ref arg b [c] |
|
||||
| A.cpp:56:10:56:10 | b [c] | A.cpp:28:8:28:10 | this [c] |
|
||||
| A.cpp:56:10:56:10 | b [c] | A.cpp:56:13:56:15 | call to get |
|
||||
| A.cpp:56:13:56:15 | call to get | A.cpp:173:26:173:26 | o |
|
||||
| A.cpp:57:11:57:24 | call to B [c] | A.cpp:57:11:57:24 | new [c] |
|
||||
| A.cpp:57:11:57:24 | new [c] | A.cpp:28:8:28:10 | this [c] |
|
||||
| A.cpp:57:11:57:24 | new [c] | A.cpp:57:28:57:30 | call to get |
|
||||
| A.cpp:57:17:57:23 | new | A.cpp:23:10:23:10 | c |
|
||||
| A.cpp:57:17:57:23 | new | A.cpp:57:11:57:24 | call to B [c] |
|
||||
| A.cpp:57:28:57:30 | call to get | A.cpp:173:26:173:26 | o |
|
||||
| A.cpp:64:10:64:15 | call to setOnB [c] | A.cpp:66:10:66:11 | b2 [c] |
|
||||
| A.cpp:64:21:64:28 | new | A.cpp:64:10:64:15 | call to setOnB [c] |
|
||||
| A.cpp:64:21:64:28 | new | A.cpp:85:26:85:26 | c |
|
||||
| A.cpp:66:10:66:11 | b2 [c] | A.cpp:66:14:66:14 | c |
|
||||
| A.cpp:66:14:66:14 | c | A.cpp:173:26:173:26 | o |
|
||||
| A.cpp:73:10:73:19 | call to setOnBWrap [c] | A.cpp:75:10:75:11 | b2 [c] |
|
||||
| A.cpp:73:25:73:32 | new | A.cpp:73:10:73:19 | call to setOnBWrap [c] |
|
||||
| A.cpp:73:25:73:32 | new | A.cpp:78:27:78:27 | c |
|
||||
| A.cpp:75:10:75:11 | b2 [c] | A.cpp:75:14:75:14 | c |
|
||||
| A.cpp:75:14:75:14 | c | A.cpp:173:26:173:26 | o |
|
||||
| A.cpp:78:27:78:27 | c | A.cpp:81:21:81:21 | c |
|
||||
| A.cpp:81:10:81:15 | call to setOnB [c] | A.cpp:82:12:82:24 | ... ? ... : ... [c] |
|
||||
| A.cpp:81:21:81:21 | c | A.cpp:81:10:81:15 | call to setOnB [c] |
|
||||
@@ -48,13 +54,20 @@ edges
|
||||
| A.cpp:103:14:103:14 | c [a] | A.cpp:107:12:107:13 | c1 [a] |
|
||||
| A.cpp:103:14:103:14 | c [a] | A.cpp:120:12:120:13 | c1 [a] |
|
||||
| A.cpp:107:12:107:13 | c1 [a] | A.cpp:107:16:107:16 | a |
|
||||
| A.cpp:107:16:107:16 | a | A.cpp:173:26:173:26 | o |
|
||||
| A.cpp:120:12:120:13 | c1 [a] | A.cpp:120:16:120:16 | a |
|
||||
| A.cpp:120:16:120:16 | a | A.cpp:173:26:173:26 | o |
|
||||
| A.cpp:124:14:124:14 | b [c] | A.cpp:131:8:131:8 | ref arg b [c] |
|
||||
| A.cpp:126:5:126:5 | ref arg b [c] | A.cpp:124:14:124:14 | b [c] |
|
||||
| A.cpp:126:5:126:5 | ref arg b [c] | A.cpp:131:8:131:8 | ref arg b [c] |
|
||||
| A.cpp:126:12:126:18 | new | A.cpp:27:17:27:17 | c |
|
||||
| A.cpp:126:12:126:18 | new | A.cpp:126:5:126:5 | ref arg b [c] |
|
||||
| A.cpp:131:8:131:8 | ref arg b [c] | A.cpp:132:10:132:10 | b [c] |
|
||||
| A.cpp:132:10:132:10 | b [c] | A.cpp:132:13:132:13 | c |
|
||||
| A.cpp:132:13:132:13 | c | A.cpp:173:26:173:26 | o |
|
||||
| A.cpp:140:13:140:13 | b | A.cpp:143:7:143:31 | ... = ... |
|
||||
| A.cpp:140:13:140:13 | b [c] | A.cpp:151:18:151:18 | ref arg b [c] |
|
||||
| A.cpp:142:7:142:7 | b [post update] [c] | A.cpp:140:13:140:13 | b [c] |
|
||||
| A.cpp:142:7:142:7 | b [post update] [c] | A.cpp:143:7:143:31 | ... = ... [c] |
|
||||
| A.cpp:142:7:142:7 | b [post update] [c] | A.cpp:151:18:151:18 | ref arg b [c] |
|
||||
| A.cpp:142:7:142:20 | ... = ... | A.cpp:142:7:142:7 | b [post update] [c] |
|
||||
@@ -66,15 +79,24 @@ edges
|
||||
| A.cpp:143:7:143:31 | ... = ... [c] | A.cpp:143:7:143:10 | this [post update] [b, c] |
|
||||
| A.cpp:143:25:143:31 | new | A.cpp:143:7:143:31 | ... = ... |
|
||||
| A.cpp:150:12:150:18 | new | A.cpp:151:18:151:18 | b |
|
||||
| A.cpp:151:12:151:24 | call to D [b, c] | A.cpp:152:10:152:10 | d [b, c] |
|
||||
| A.cpp:151:12:151:24 | call to D [b, c] | A.cpp:153:10:153:10 | d [b, c] |
|
||||
| A.cpp:151:12:151:24 | call to D [b] | A.cpp:152:10:152:10 | d [b] |
|
||||
| A.cpp:151:18:151:18 | b | A.cpp:140:13:140:13 | b |
|
||||
| A.cpp:151:18:151:18 | b | A.cpp:151:12:151:24 | call to D [b] |
|
||||
| A.cpp:151:18:151:18 | ref arg b [c] | A.cpp:154:10:154:10 | b [c] |
|
||||
| A.cpp:152:10:152:10 | d [b, c] | A.cpp:152:13:152:13 | b [c] |
|
||||
| A.cpp:152:10:152:10 | d [b] | A.cpp:152:13:152:13 | b |
|
||||
| A.cpp:152:10:152:10 | d [post update] [b, c] | A.cpp:153:10:153:10 | d [b, c] |
|
||||
| A.cpp:152:13:152:13 | b | A.cpp:173:26:173:26 | o |
|
||||
| A.cpp:152:13:152:13 | b [c] | A.cpp:152:13:152:13 | ref arg b [c] |
|
||||
| A.cpp:152:13:152:13 | b [c] | A.cpp:173:26:173:26 | o [c] |
|
||||
| A.cpp:152:13:152:13 | ref arg b [c] | A.cpp:152:10:152:10 | d [post update] [b, c] |
|
||||
| A.cpp:153:10:153:10 | d [b, c] | A.cpp:153:13:153:13 | b [c] |
|
||||
| A.cpp:153:13:153:13 | b [c] | A.cpp:153:16:153:16 | c |
|
||||
| A.cpp:153:16:153:16 | c | A.cpp:173:26:173:26 | o |
|
||||
| A.cpp:154:10:154:10 | b [c] | A.cpp:154:13:154:13 | c |
|
||||
| A.cpp:154:13:154:13 | c | A.cpp:173:26:173:26 | o |
|
||||
| A.cpp:159:12:159:18 | new | A.cpp:160:29:160:29 | b |
|
||||
| A.cpp:160:18:160:60 | call to MyList [head] | A.cpp:161:38:161:39 | l1 [head] |
|
||||
| A.cpp:160:29:160:29 | b | A.cpp:160:18:160:60 | call to MyList [head] |
|
||||
@@ -87,13 +109,23 @@ edges
|
||||
| A.cpp:162:38:162:39 | l2 [next, head] | A.cpp:162:18:162:40 | call to MyList [next, next, head] |
|
||||
| A.cpp:162:38:162:39 | l2 [next, head] | A.cpp:181:32:181:35 | next [next, head] |
|
||||
| A.cpp:165:10:165:11 | l3 [next, next, head] | A.cpp:165:14:165:17 | next [next, head] |
|
||||
| A.cpp:165:10:165:11 | l3 [post update] [next, next, head] | A.cpp:167:44:167:44 | l [next, next, head] |
|
||||
| A.cpp:165:14:165:17 | next [next, head] | A.cpp:165:20:165:23 | next [head] |
|
||||
| A.cpp:165:14:165:17 | next [post update] [next, head] | A.cpp:165:10:165:11 | l3 [post update] [next, next, head] |
|
||||
| A.cpp:165:20:165:23 | next [head] | A.cpp:165:26:165:29 | head |
|
||||
| A.cpp:165:20:165:23 | next [head] | A.cpp:165:26:165:29 | head |
|
||||
| A.cpp:165:20:165:23 | next [post update] [head] | A.cpp:165:14:165:17 | next [post update] [next, head] |
|
||||
| A.cpp:165:26:165:29 | head | A.cpp:165:26:165:29 | ref arg head |
|
||||
| A.cpp:165:26:165:29 | head | A.cpp:173:26:173:26 | o |
|
||||
| A.cpp:165:26:165:29 | ref arg head | A.cpp:165:20:165:23 | next [post update] [head] |
|
||||
| A.cpp:167:44:167:44 | l [next, head] | A.cpp:167:47:167:50 | next [head] |
|
||||
| A.cpp:167:44:167:44 | l [next, next, head] | A.cpp:167:47:167:50 | next [next, head] |
|
||||
| A.cpp:167:47:167:50 | next [head] | A.cpp:169:12:169:12 | l [head] |
|
||||
| A.cpp:167:47:167:50 | next [next, head] | A.cpp:167:44:167:44 | l [next, head] |
|
||||
| A.cpp:169:12:169:12 | l [head] | A.cpp:169:15:169:18 | head |
|
||||
| A.cpp:169:15:169:18 | head | A.cpp:173:26:173:26 | o |
|
||||
| A.cpp:173:26:173:26 | o | A.cpp:173:26:173:26 | o |
|
||||
| A.cpp:173:26:173:26 | o [c] | A.cpp:173:26:173:26 | o [c] |
|
||||
| A.cpp:181:15:181:21 | newHead | A.cpp:183:7:183:20 | ... = ... |
|
||||
| A.cpp:181:32:181:35 | next [head] | A.cpp:184:7:184:23 | ... = ... [head] |
|
||||
| A.cpp:181:32:181:35 | next [next, head] | A.cpp:184:7:184:23 | ... = ... [next, head] |
|
||||
@@ -150,6 +182,7 @@ edges
|
||||
| D.cpp:22:10:22:11 | b2 [box, elem] | D.cpp:22:14:22:20 | call to getBox1 [elem] |
|
||||
| D.cpp:22:14:22:20 | call to getBox1 [elem] | D.cpp:10:11:10:17 | this [elem] |
|
||||
| D.cpp:22:14:22:20 | call to getBox1 [elem] | D.cpp:22:25:22:31 | call to getElem |
|
||||
| D.cpp:22:25:22:31 | call to getElem | realistic.cpp:41:17:41:17 | o |
|
||||
| D.cpp:28:15:28:24 | new | D.cpp:30:5:30:20 | ... = ... |
|
||||
| D.cpp:30:5:30:5 | b [post update] [box, elem] | D.cpp:31:14:31:14 | b [box, elem] |
|
||||
| D.cpp:30:5:30:20 | ... = ... | D.cpp:30:8:30:10 | box [post update] [elem] |
|
||||
@@ -182,17 +215,23 @@ edges
|
||||
| D.cpp:64:10:64:17 | boxfield [box, elem] | D.cpp:64:20:64:22 | box [elem] |
|
||||
| D.cpp:64:10:64:17 | this [boxfield, box, elem] | D.cpp:64:10:64:17 | boxfield [box, elem] |
|
||||
| D.cpp:64:20:64:22 | box [elem] | D.cpp:64:25:64:28 | elem |
|
||||
| D.cpp:64:25:64:28 | elem | realistic.cpp:41:17:41:17 | o |
|
||||
| E.cpp:19:27:19:27 | p [data, buffer] | E.cpp:21:10:21:10 | p [data, buffer] |
|
||||
| E.cpp:21:10:21:10 | p [data, buffer] | E.cpp:21:13:21:16 | data [buffer] |
|
||||
| E.cpp:21:13:21:16 | data [buffer] | E.cpp:21:18:21:23 | buffer |
|
||||
| E.cpp:21:18:21:23 | buffer | realistic.cpp:41:17:41:17 | o |
|
||||
| E.cpp:28:21:28:23 | ref arg raw | E.cpp:31:10:31:12 | raw |
|
||||
| E.cpp:29:21:29:21 | b [post update] [buffer] | E.cpp:32:10:32:10 | b [buffer] |
|
||||
| E.cpp:29:24:29:29 | ref arg buffer | E.cpp:29:21:29:21 | b [post update] [buffer] |
|
||||
| E.cpp:30:21:30:21 | p [post update] [data, buffer] | E.cpp:33:18:33:19 | & ... [data, buffer] |
|
||||
| E.cpp:30:23:30:26 | data [post update] [buffer] | E.cpp:30:21:30:21 | p [post update] [data, buffer] |
|
||||
| E.cpp:30:28:30:33 | ref arg buffer | E.cpp:30:23:30:26 | data [post update] [buffer] |
|
||||
| E.cpp:31:10:31:12 | raw | realistic.cpp:41:17:41:17 | o |
|
||||
| E.cpp:32:10:32:10 | b [buffer] | E.cpp:32:13:32:18 | buffer |
|
||||
| E.cpp:32:13:32:18 | buffer | realistic.cpp:41:17:41:17 | o |
|
||||
| E.cpp:33:18:33:19 | & ... [data, buffer] | E.cpp:19:27:19:27 | p [data, buffer] |
|
||||
| aliasing.cpp:8:23:8:23 | s [m1] | aliasing.cpp:25:17:25:19 | ref arg & ... [m1] |
|
||||
| aliasing.cpp:9:3:9:3 | s [post update] [m1] | aliasing.cpp:8:23:8:23 | s [m1] |
|
||||
| aliasing.cpp:9:3:9:3 | s [post update] [m1] | aliasing.cpp:25:17:25:19 | ref arg & ... [m1] |
|
||||
| aliasing.cpp:9:3:9:22 | ... = ... | aliasing.cpp:9:3:9:3 | s [post update] [m1] |
|
||||
| aliasing.cpp:9:11:9:20 | call to user_input | aliasing.cpp:9:3:9:22 | ... = ... |
|
||||
@@ -204,30 +243,42 @@ edges
|
||||
| aliasing.cpp:25:17:25:19 | ref arg & ... [m1] | aliasing.cpp:29:8:29:9 | s1 [m1] |
|
||||
| aliasing.cpp:26:19:26:20 | ref arg s2 [m1] | aliasing.cpp:30:8:30:9 | s2 [m1] |
|
||||
| aliasing.cpp:29:8:29:9 | s1 [m1] | aliasing.cpp:29:11:29:12 | m1 |
|
||||
| aliasing.cpp:29:11:29:12 | m1 | realistic.cpp:41:17:41:17 | o |
|
||||
| aliasing.cpp:30:8:30:9 | s2 [m1] | aliasing.cpp:30:11:30:12 | m1 |
|
||||
| aliasing.cpp:30:11:30:12 | m1 | realistic.cpp:41:17:41:17 | o |
|
||||
| aliasing.cpp:60:3:60:4 | s2 [post update] [m1] | aliasing.cpp:62:8:62:12 | copy2 [m1] |
|
||||
| aliasing.cpp:60:3:60:22 | ... = ... | aliasing.cpp:60:3:60:4 | s2 [post update] [m1] |
|
||||
| aliasing.cpp:60:11:60:20 | call to user_input | aliasing.cpp:60:3:60:22 | ... = ... |
|
||||
| aliasing.cpp:62:8:62:12 | copy2 [m1] | aliasing.cpp:62:14:62:15 | m1 |
|
||||
| aliasing.cpp:62:14:62:15 | m1 | realistic.cpp:41:17:41:17 | o |
|
||||
| aliasing.cpp:92:3:92:3 | w [post update] [s, m1] | aliasing.cpp:93:8:93:8 | w [s, m1] |
|
||||
| aliasing.cpp:92:3:92:23 | ... = ... | aliasing.cpp:92:5:92:5 | s [post update] [m1] |
|
||||
| aliasing.cpp:92:5:92:5 | s [post update] [m1] | aliasing.cpp:92:3:92:3 | w [post update] [s, m1] |
|
||||
| aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:92:3:92:23 | ... = ... |
|
||||
| aliasing.cpp:93:8:93:8 | w [s, m1] | aliasing.cpp:93:10:93:10 | s [m1] |
|
||||
| aliasing.cpp:93:10:93:10 | s [m1] | aliasing.cpp:93:12:93:13 | m1 |
|
||||
| aliasing.cpp:93:12:93:13 | m1 | realistic.cpp:41:17:41:17 | o |
|
||||
| aliasing.cpp:105:23:105:24 | pa | aliasing.cpp:158:17:158:20 | ref arg data |
|
||||
| aliasing.cpp:105:23:105:24 | pa | aliasing.cpp:164:17:164:20 | ref arg data |
|
||||
| aliasing.cpp:105:23:105:24 | pa | aliasing.cpp:175:15:175:22 | ref arg & ... |
|
||||
| aliasing.cpp:105:23:105:24 | pa | aliasing.cpp:187:15:187:22 | ref arg & ... |
|
||||
| aliasing.cpp:105:23:105:24 | pa | aliasing.cpp:200:15:200:24 | ref arg & ... |
|
||||
| aliasing.cpp:106:4:106:5 | pa [inner post update] | aliasing.cpp:158:17:158:20 | ref arg data |
|
||||
| aliasing.cpp:106:4:106:5 | pa [inner post update] | aliasing.cpp:164:17:164:20 | ref arg data |
|
||||
| aliasing.cpp:106:4:106:5 | pa [inner post update] | aliasing.cpp:175:15:175:22 | ref arg & ... |
|
||||
| aliasing.cpp:106:4:106:5 | pa [inner post update] | aliasing.cpp:187:15:187:22 | ref arg & ... |
|
||||
| aliasing.cpp:106:4:106:5 | pa [inner post update] | aliasing.cpp:200:15:200:24 | ref arg & ... |
|
||||
| aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:105:23:105:24 | pa |
|
||||
| aliasing.cpp:106:9:106:18 | call to user_input | aliasing.cpp:106:4:106:5 | pa [inner post update] |
|
||||
| aliasing.cpp:158:15:158:15 | s [post update] [data] | aliasing.cpp:159:9:159:9 | s [data] |
|
||||
| aliasing.cpp:158:17:158:20 | ref arg data | aliasing.cpp:158:15:158:15 | s [post update] [data] |
|
||||
| aliasing.cpp:159:8:159:14 | * ... | realistic.cpp:41:17:41:17 | o |
|
||||
| aliasing.cpp:159:9:159:9 | s [data] | aliasing.cpp:159:11:159:14 | data |
|
||||
| aliasing.cpp:159:11:159:14 | data | aliasing.cpp:159:8:159:14 | * ... |
|
||||
| aliasing.cpp:164:15:164:15 | s [post update] [data] | aliasing.cpp:165:8:165:8 | s [data] |
|
||||
| aliasing.cpp:164:17:164:20 | ref arg data | aliasing.cpp:164:15:164:15 | s [post update] [data] |
|
||||
| aliasing.cpp:165:8:165:8 | s [data] | aliasing.cpp:165:10:165:13 | data |
|
||||
| aliasing.cpp:165:8:165:16 | access to array | realistic.cpp:41:17:41:17 | o |
|
||||
| aliasing.cpp:165:10:165:13 | data | aliasing.cpp:165:8:165:16 | access to array |
|
||||
| aliasing.cpp:175:15:175:22 | ref arg & ... | aliasing.cpp:175:21:175:22 | m1 [inner post update] |
|
||||
| aliasing.cpp:175:16:175:17 | s2 [post update] [s, m1] | aliasing.cpp:176:8:176:9 | s2 [s, m1] |
|
||||
@@ -235,24 +286,33 @@ edges
|
||||
| aliasing.cpp:175:21:175:22 | m1 [inner post update] | aliasing.cpp:175:19:175:19 | s [post update] [m1] |
|
||||
| aliasing.cpp:176:8:176:9 | s2 [s, m1] | aliasing.cpp:176:11:176:11 | s [m1] |
|
||||
| aliasing.cpp:176:11:176:11 | s [m1] | aliasing.cpp:176:13:176:14 | m1 |
|
||||
| aliasing.cpp:176:13:176:14 | m1 | realistic.cpp:41:17:41:17 | o |
|
||||
| aliasing.cpp:187:15:187:22 | ref arg & ... | aliasing.cpp:187:21:187:22 | m1 [inner post update] |
|
||||
| aliasing.cpp:187:16:187:17 | s2 [post update] [s, m1] | aliasing.cpp:189:8:189:11 | s2_2 [s, m1] |
|
||||
| aliasing.cpp:187:19:187:19 | s [post update] [m1] | aliasing.cpp:187:16:187:17 | s2 [post update] [s, m1] |
|
||||
| aliasing.cpp:187:21:187:22 | m1 [inner post update] | aliasing.cpp:187:19:187:19 | s [post update] [m1] |
|
||||
| aliasing.cpp:189:8:189:11 | s2_2 [s, m1] | aliasing.cpp:189:13:189:13 | s [m1] |
|
||||
| aliasing.cpp:189:13:189:13 | s [m1] | aliasing.cpp:189:15:189:16 | m1 |
|
||||
| aliasing.cpp:189:15:189:16 | m1 | realistic.cpp:41:17:41:17 | o |
|
||||
| aliasing.cpp:200:15:200:24 | ref arg & ... | aliasing.cpp:200:23:200:24 | m1 [inner post update] |
|
||||
| aliasing.cpp:200:16:200:18 | ps2 [post update] [s, m1] | aliasing.cpp:201:8:201:10 | ps2 [s, m1] |
|
||||
| aliasing.cpp:200:21:200:21 | s [post update] [m1] | aliasing.cpp:200:16:200:18 | ps2 [post update] [s, m1] |
|
||||
| aliasing.cpp:200:23:200:24 | m1 [inner post update] | aliasing.cpp:200:21:200:21 | s [post update] [m1] |
|
||||
| aliasing.cpp:201:8:201:10 | ps2 [s, m1] | aliasing.cpp:201:13:201:13 | s [m1] |
|
||||
| aliasing.cpp:201:13:201:13 | s [m1] | aliasing.cpp:201:15:201:16 | m1 |
|
||||
| aliasing.cpp:201:15:201:16 | m1 | realistic.cpp:41:17:41:17 | o |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:7:8:7:13 | access to array |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:8:8:8:13 | access to array |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:9:8:9:11 | * ... |
|
||||
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:10:8:10:15 | * ... |
|
||||
| arrays.cpp:7:8:7:13 | access to array | realistic.cpp:41:17:41:17 | o |
|
||||
| arrays.cpp:8:8:8:13 | access to array | realistic.cpp:41:17:41:17 | o |
|
||||
| arrays.cpp:9:8:9:11 | * ... | realistic.cpp:41:17:41:17 | o |
|
||||
| arrays.cpp:10:8:10:15 | * ... | realistic.cpp:41:17:41:17 | o |
|
||||
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:16:8:16:13 | access to array |
|
||||
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:17:8:17:13 | access to array |
|
||||
| arrays.cpp:16:8:16:13 | access to array | realistic.cpp:41:17:41:17 | o |
|
||||
| arrays.cpp:17:8:17:13 | access to array | realistic.cpp:41:17:41:17 | o |
|
||||
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, data] | arrays.cpp:37:8:37:8 | o [nested, arr, data] |
|
||||
| arrays.cpp:36:3:36:3 | o [post update] [nested, arr, data] | arrays.cpp:38:8:38:8 | o [nested, arr, data] |
|
||||
| arrays.cpp:36:3:36:17 | access to array [post update] [data] | arrays.cpp:36:12:36:14 | arr [inner post update] [data] |
|
||||
@@ -261,13 +321,22 @@ edges
|
||||
| arrays.cpp:36:12:36:14 | arr [inner post update] [data] | arrays.cpp:36:5:36:10 | nested [post update] [arr, data] |
|
||||
| arrays.cpp:36:26:36:35 | call to user_input | arrays.cpp:36:3:36:37 | ... = ... |
|
||||
| arrays.cpp:37:8:37:8 | o [nested, arr, data] | arrays.cpp:37:10:37:15 | nested [arr, data] |
|
||||
| arrays.cpp:37:8:37:8 | o [post update] [nested, arr, data] | arrays.cpp:38:8:38:8 | o [nested, arr, data] |
|
||||
| arrays.cpp:37:8:37:22 | access to array [data] | arrays.cpp:37:24:37:27 | data |
|
||||
| arrays.cpp:37:8:37:22 | access to array [data] | arrays.cpp:37:24:37:27 | data |
|
||||
| arrays.cpp:37:8:37:22 | access to array [post update] [data] | arrays.cpp:37:17:37:19 | arr [inner post update] [data] |
|
||||
| arrays.cpp:37:10:37:15 | nested [arr, data] | arrays.cpp:37:17:37:19 | arr [data] |
|
||||
| arrays.cpp:37:10:37:15 | nested [post update] [arr, data] | arrays.cpp:37:8:37:8 | o [post update] [nested, arr, data] |
|
||||
| arrays.cpp:37:17:37:19 | arr [data] | arrays.cpp:37:8:37:22 | access to array [data] |
|
||||
| arrays.cpp:37:17:37:19 | arr [inner post update] [data] | arrays.cpp:37:10:37:15 | nested [post update] [arr, data] |
|
||||
| arrays.cpp:37:24:37:27 | data | arrays.cpp:37:24:37:27 | ref arg data |
|
||||
| arrays.cpp:37:24:37:27 | data | realistic.cpp:41:17:41:17 | o |
|
||||
| arrays.cpp:37:24:37:27 | ref arg data | arrays.cpp:37:8:37:22 | access to array [post update] [data] |
|
||||
| arrays.cpp:38:8:38:8 | o [nested, arr, data] | arrays.cpp:38:10:38:15 | nested [arr, data] |
|
||||
| arrays.cpp:38:8:38:22 | access to array [data] | arrays.cpp:38:24:38:27 | data |
|
||||
| arrays.cpp:38:10:38:15 | nested [arr, data] | arrays.cpp:38:17:38:19 | arr [data] |
|
||||
| arrays.cpp:38:17:38:19 | arr [data] | arrays.cpp:38:8:38:22 | access to array [data] |
|
||||
| arrays.cpp:38:24:38:27 | data | realistic.cpp:41:17:41:17 | o |
|
||||
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, data] | arrays.cpp:43:8:43:8 | o [indirect, arr, data] |
|
||||
| arrays.cpp:42:3:42:3 | o [post update] [indirect, arr, data] | arrays.cpp:44:8:44:8 | o [indirect, arr, data] |
|
||||
| arrays.cpp:42:3:42:20 | access to array [post update] [data] | arrays.cpp:42:15:42:17 | arr [inner post update] [data] |
|
||||
@@ -276,14 +345,24 @@ edges
|
||||
| arrays.cpp:42:15:42:17 | arr [inner post update] [data] | arrays.cpp:42:5:42:12 | indirect [post update] [arr, data] |
|
||||
| arrays.cpp:42:29:42:38 | call to user_input | arrays.cpp:42:3:42:40 | ... = ... |
|
||||
| arrays.cpp:43:8:43:8 | o [indirect, arr, data] | arrays.cpp:43:10:43:17 | indirect [arr, data] |
|
||||
| arrays.cpp:43:8:43:8 | o [post update] [indirect, arr, data] | arrays.cpp:44:8:44:8 | o [indirect, arr, data] |
|
||||
| arrays.cpp:43:8:43:25 | access to array [data] | arrays.cpp:43:27:43:30 | data |
|
||||
| arrays.cpp:43:8:43:25 | access to array [data] | arrays.cpp:43:27:43:30 | data |
|
||||
| arrays.cpp:43:8:43:25 | access to array [post update] [data] | arrays.cpp:43:20:43:22 | arr [inner post update] [data] |
|
||||
| arrays.cpp:43:10:43:17 | indirect [arr, data] | arrays.cpp:43:20:43:22 | arr [data] |
|
||||
| arrays.cpp:43:10:43:17 | indirect [post update] [arr, data] | arrays.cpp:43:8:43:8 | o [post update] [indirect, arr, data] |
|
||||
| arrays.cpp:43:20:43:22 | arr [data] | arrays.cpp:43:8:43:25 | access to array [data] |
|
||||
| arrays.cpp:43:20:43:22 | arr [inner post update] [data] | arrays.cpp:43:10:43:17 | indirect [post update] [arr, data] |
|
||||
| arrays.cpp:43:27:43:30 | data | arrays.cpp:43:27:43:30 | ref arg data |
|
||||
| arrays.cpp:43:27:43:30 | data | realistic.cpp:41:17:41:17 | o |
|
||||
| arrays.cpp:43:27:43:30 | ref arg data | arrays.cpp:43:8:43:25 | access to array [post update] [data] |
|
||||
| arrays.cpp:44:8:44:8 | o [indirect, arr, data] | arrays.cpp:44:10:44:17 | indirect [arr, data] |
|
||||
| arrays.cpp:44:8:44:25 | access to array [data] | arrays.cpp:44:27:44:30 | data |
|
||||
| arrays.cpp:44:10:44:17 | indirect [arr, data] | arrays.cpp:44:20:44:22 | arr [data] |
|
||||
| arrays.cpp:44:20:44:22 | arr [data] | arrays.cpp:44:8:44:25 | access to array [data] |
|
||||
| arrays.cpp:44:27:44:30 | data | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | ... = ... |
|
||||
| by_reference.cpp:12:5:12:5 | s [post update] [a] | by_reference.cpp:11:39:11:39 | s [a] |
|
||||
| by_reference.cpp:12:5:12:16 | ... = ... | by_reference.cpp:12:5:12:5 | s [post update] [a] |
|
||||
| by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:19 | ... = ... |
|
||||
| by_reference.cpp:16:5:16:19 | ... = ... | by_reference.cpp:16:5:16:8 | this [post update] [a] |
|
||||
@@ -308,21 +387,30 @@ edges
|
||||
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:50:3:50:3 | ref arg s [a] |
|
||||
| by_reference.cpp:51:8:51:8 | s [a] | by_reference.cpp:35:9:35:19 | this [a] |
|
||||
| by_reference.cpp:51:8:51:8 | s [a] | by_reference.cpp:51:10:51:20 | call to getDirectly |
|
||||
| by_reference.cpp:51:10:51:20 | call to getDirectly | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:56:3:56:3 | ref arg s [a] | by_reference.cpp:57:8:57:8 | s [a] |
|
||||
| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:19:28:19:32 | value |
|
||||
| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:56:3:56:3 | ref arg s [a] |
|
||||
| by_reference.cpp:57:8:57:8 | s [a] | by_reference.cpp:39:9:39:21 | this [a] |
|
||||
| by_reference.cpp:57:8:57:8 | s [a] | by_reference.cpp:57:10:57:22 | call to getIndirectly |
|
||||
| by_reference.cpp:57:10:57:22 | call to getIndirectly | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:62:3:62:3 | ref arg s [a] | by_reference.cpp:63:8:63:8 | s [a] |
|
||||
| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:23:34:23:38 | value |
|
||||
| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:62:3:62:3 | ref arg s [a] |
|
||||
| by_reference.cpp:63:8:63:8 | s [a] | by_reference.cpp:43:9:43:27 | this [a] |
|
||||
| by_reference.cpp:63:8:63:8 | s [a] | by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
|
||||
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:68:17:68:18 | ref arg & ... [a] | by_reference.cpp:69:22:69:23 | & ... [a] |
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:11:48:11:52 | value |
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:68:17:68:18 | ref arg & ... [a] |
|
||||
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:69:22:69:23 | & ... [a] | by_reference.cpp:31:46:31:46 | s [a] |
|
||||
| by_reference.cpp:69:22:69:23 | & ... [a] | by_reference.cpp:69:8:69:20 | call to nonMemberGetA |
|
||||
| by_reference.cpp:83:31:83:35 | inner [a] | by_reference.cpp:102:21:102:39 | ref arg & ... [a] |
|
||||
| by_reference.cpp:83:31:83:35 | inner [a] | by_reference.cpp:103:27:103:35 | ref arg inner_ptr [a] |
|
||||
| by_reference.cpp:83:31:83:35 | inner [a] | by_reference.cpp:106:21:106:41 | ref arg & ... [a] |
|
||||
| by_reference.cpp:83:31:83:35 | inner [a] | by_reference.cpp:107:29:107:37 | ref arg inner_ptr [a] |
|
||||
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:83:31:83:35 | inner [a] |
|
||||
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:102:21:102:39 | ref arg & ... [a] |
|
||||
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:103:27:103:35 | ref arg inner_ptr [a] |
|
||||
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:106:21:106:41 | ref arg & ... [a] |
|
||||
@@ -340,8 +428,11 @@ edges
|
||||
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | by_reference.cpp:127:21:127:38 | ref arg * ... [a] |
|
||||
| by_reference.cpp:88:3:88:24 | ... = ... | by_reference.cpp:88:3:88:7 | inner [post update] [a] |
|
||||
| by_reference.cpp:88:13:88:22 | call to user_input | by_reference.cpp:88:3:88:24 | ... = ... |
|
||||
| by_reference.cpp:91:25:91:26 | pa | by_reference.cpp:104:15:104:22 | ref arg & ... |
|
||||
| by_reference.cpp:91:25:91:26 | pa | by_reference.cpp:108:15:108:24 | ref arg & ... |
|
||||
| by_reference.cpp:92:4:92:5 | pa [inner post update] | by_reference.cpp:104:15:104:22 | ref arg & ... |
|
||||
| by_reference.cpp:92:4:92:5 | pa [inner post update] | by_reference.cpp:108:15:108:24 | ref arg & ... |
|
||||
| by_reference.cpp:92:9:92:18 | call to user_input | by_reference.cpp:91:25:91:26 | pa |
|
||||
| by_reference.cpp:92:9:92:18 | call to user_input | by_reference.cpp:92:4:92:5 | pa [inner post update] |
|
||||
| by_reference.cpp:95:25:95:26 | pa | by_reference.cpp:124:21:124:21 | ref arg a |
|
||||
| by_reference.cpp:95:25:95:26 | pa | by_reference.cpp:128:23:128:23 | ref arg a |
|
||||
@@ -364,14 +455,20 @@ edges
|
||||
| by_reference.cpp:108:24:108:24 | a [inner post update] | by_reference.cpp:108:16:108:21 | pouter [post update] [a] |
|
||||
| by_reference.cpp:110:8:110:12 | outer [inner_nested, a] | by_reference.cpp:110:14:110:25 | inner_nested [a] |
|
||||
| by_reference.cpp:110:14:110:25 | inner_nested [a] | by_reference.cpp:110:27:110:27 | a |
|
||||
| by_reference.cpp:110:27:110:27 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:111:8:111:12 | outer [inner_ptr, a] | by_reference.cpp:111:14:111:22 | inner_ptr [a] |
|
||||
| by_reference.cpp:111:14:111:22 | inner_ptr [a] | by_reference.cpp:111:25:111:25 | a |
|
||||
| by_reference.cpp:111:25:111:25 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:112:8:112:12 | outer [a] | by_reference.cpp:112:14:112:14 | a |
|
||||
| by_reference.cpp:112:14:112:14 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:114:8:114:13 | pouter [inner_nested, a] | by_reference.cpp:114:16:114:27 | inner_nested [a] |
|
||||
| by_reference.cpp:114:16:114:27 | inner_nested [a] | by_reference.cpp:114:29:114:29 | a |
|
||||
| by_reference.cpp:114:29:114:29 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:115:8:115:13 | pouter [inner_ptr, a] | by_reference.cpp:115:16:115:24 | inner_ptr [a] |
|
||||
| by_reference.cpp:115:16:115:24 | inner_ptr [a] | by_reference.cpp:115:27:115:27 | a |
|
||||
| by_reference.cpp:115:27:115:27 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:116:8:116:13 | pouter [a] | by_reference.cpp:116:16:116:16 | a |
|
||||
| by_reference.cpp:116:16:116:16 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:122:21:122:25 | outer [post update] [inner_nested, a] | by_reference.cpp:130:8:130:12 | outer [inner_nested, a] |
|
||||
| by_reference.cpp:122:27:122:38 | ref arg inner_nested [a] | by_reference.cpp:122:21:122:25 | outer [post update] [inner_nested, a] |
|
||||
| by_reference.cpp:123:21:123:36 | ref arg * ... [a] | by_reference.cpp:123:28:123:36 | inner_ptr [inner post update] [a] |
|
||||
@@ -388,14 +485,20 @@ edges
|
||||
| by_reference.cpp:128:23:128:23 | ref arg a | by_reference.cpp:128:15:128:20 | pouter [post update] [a] |
|
||||
| by_reference.cpp:130:8:130:12 | outer [inner_nested, a] | by_reference.cpp:130:14:130:25 | inner_nested [a] |
|
||||
| by_reference.cpp:130:14:130:25 | inner_nested [a] | by_reference.cpp:130:27:130:27 | a |
|
||||
| by_reference.cpp:130:27:130:27 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:131:8:131:12 | outer [inner_ptr, a] | by_reference.cpp:131:14:131:22 | inner_ptr [a] |
|
||||
| by_reference.cpp:131:14:131:22 | inner_ptr [a] | by_reference.cpp:131:25:131:25 | a |
|
||||
| by_reference.cpp:131:25:131:25 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:132:8:132:12 | outer [a] | by_reference.cpp:132:14:132:14 | a |
|
||||
| by_reference.cpp:132:14:132:14 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:134:8:134:13 | pouter [inner_nested, a] | by_reference.cpp:134:16:134:27 | inner_nested [a] |
|
||||
| by_reference.cpp:134:16:134:27 | inner_nested [a] | by_reference.cpp:134:29:134:29 | a |
|
||||
| by_reference.cpp:134:29:134:29 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:135:8:135:13 | pouter [inner_ptr, a] | by_reference.cpp:135:16:135:24 | inner_ptr [a] |
|
||||
| by_reference.cpp:135:16:135:24 | inner_ptr [a] | by_reference.cpp:135:27:135:27 | a |
|
||||
| by_reference.cpp:135:27:135:27 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| by_reference.cpp:136:8:136:13 | pouter [a] | by_reference.cpp:136:16:136:16 | a |
|
||||
| by_reference.cpp:136:16:136:16 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| complex.cpp:9:7:9:7 | this [a_] | complex.cpp:9:20:9:21 | this [a_] |
|
||||
| complex.cpp:9:20:9:21 | this [a_] | complex.cpp:9:20:9:21 | a_ |
|
||||
| complex.cpp:10:7:10:7 | this [b_] | complex.cpp:10:20:10:21 | this [b_] |
|
||||
@@ -439,26 +542,31 @@ edges
|
||||
| complex.cpp:65:7:65:8 | b3 [inner, f, a_] | complex.cpp:40:17:40:17 | b [inner, f, a_] |
|
||||
| complex.cpp:65:7:65:8 | b3 [inner, f, b_] | complex.cpp:40:17:40:17 | b [inner, f, b_] |
|
||||
| conflated.cpp:19:19:19:21 | ref arg raw | conflated.cpp:20:8:20:10 | raw |
|
||||
| conflated.cpp:20:8:20:10 | raw | realistic.cpp:41:17:41:17 | o |
|
||||
| conflated.cpp:29:3:29:4 | pa [post update] [x] | conflated.cpp:30:8:30:9 | pa [x] |
|
||||
| conflated.cpp:29:3:29:22 | ... = ... | conflated.cpp:29:3:29:4 | pa [post update] [x] |
|
||||
| conflated.cpp:29:11:29:20 | call to user_input | conflated.cpp:29:3:29:22 | ... = ... |
|
||||
| conflated.cpp:30:8:30:9 | pa [x] | conflated.cpp:30:12:30:12 | x |
|
||||
| conflated.cpp:30:12:30:12 | x | realistic.cpp:41:17:41:17 | o |
|
||||
| conflated.cpp:36:3:36:4 | pa [post update] [x] | conflated.cpp:37:8:37:9 | pa [x] |
|
||||
| conflated.cpp:36:3:36:22 | ... = ... | conflated.cpp:36:3:36:4 | pa [post update] [x] |
|
||||
| conflated.cpp:36:11:36:20 | call to user_input | conflated.cpp:36:3:36:22 | ... = ... |
|
||||
| conflated.cpp:37:8:37:9 | pa [x] | conflated.cpp:37:12:37:12 | x |
|
||||
| conflated.cpp:37:12:37:12 | x | realistic.cpp:41:17:41:17 | o |
|
||||
| conflated.cpp:54:3:54:4 | ll [post update] [next, y] | conflated.cpp:55:8:55:9 | ll [next, y] |
|
||||
| conflated.cpp:54:3:54:28 | ... = ... | conflated.cpp:54:7:54:10 | next [post update] [y] |
|
||||
| conflated.cpp:54:7:54:10 | next [post update] [y] | conflated.cpp:54:3:54:4 | ll [post update] [next, y] |
|
||||
| conflated.cpp:54:17:54:26 | call to user_input | conflated.cpp:54:3:54:28 | ... = ... |
|
||||
| conflated.cpp:55:8:55:9 | ll [next, y] | conflated.cpp:55:12:55:15 | next [y] |
|
||||
| conflated.cpp:55:12:55:15 | next [y] | conflated.cpp:55:18:55:18 | y |
|
||||
| conflated.cpp:55:18:55:18 | y | realistic.cpp:41:17:41:17 | o |
|
||||
| conflated.cpp:60:3:60:4 | ll [post update] [next, y] | conflated.cpp:61:8:61:9 | ll [next, y] |
|
||||
| conflated.cpp:60:3:60:28 | ... = ... | conflated.cpp:60:7:60:10 | next [post update] [y] |
|
||||
| conflated.cpp:60:7:60:10 | next [post update] [y] | conflated.cpp:60:3:60:4 | ll [post update] [next, y] |
|
||||
| conflated.cpp:60:17:60:26 | call to user_input | conflated.cpp:60:3:60:28 | ... = ... |
|
||||
| conflated.cpp:61:8:61:9 | ll [next, y] | conflated.cpp:61:12:61:15 | next [y] |
|
||||
| conflated.cpp:61:12:61:15 | next [y] | conflated.cpp:61:18:61:18 | y |
|
||||
| conflated.cpp:61:18:61:18 | y | realistic.cpp:41:17:41:17 | o |
|
||||
| constructors.cpp:18:9:18:9 | this [a_] | constructors.cpp:18:22:18:23 | this [a_] |
|
||||
| constructors.cpp:18:22:18:23 | this [a_] | constructors.cpp:18:22:18:23 | a_ |
|
||||
| constructors.cpp:19:9:19:9 | this [b_] | constructors.cpp:19:22:19:23 | this [b_] |
|
||||
@@ -492,6 +600,7 @@ edges
|
||||
| qualifiers.cpp:9:21:9:25 | value | qualifiers.cpp:9:30:9:44 | ... = ... |
|
||||
| qualifiers.cpp:9:30:9:44 | ... = ... | qualifiers.cpp:9:30:9:33 | this [post update] [a] |
|
||||
| qualifiers.cpp:12:40:12:44 | value | qualifiers.cpp:12:49:12:64 | ... = ... |
|
||||
| qualifiers.cpp:12:49:12:53 | inner [post update] [a] | qualifiers.cpp:12:27:12:31 | inner [a] |
|
||||
| qualifiers.cpp:12:49:12:64 | ... = ... | qualifiers.cpp:12:49:12:53 | inner [post update] [a] |
|
||||
| qualifiers.cpp:13:42:13:46 | value | qualifiers.cpp:13:51:13:65 | ... = ... |
|
||||
| qualifiers.cpp:13:51:13:55 | inner [post update] [a] | qualifiers.cpp:13:29:13:33 | inner [a] |
|
||||
@@ -502,18 +611,21 @@ edges
|
||||
| qualifiers.cpp:22:27:22:36 | call to user_input | qualifiers.cpp:22:5:22:38 | ... = ... |
|
||||
| qualifiers.cpp:23:10:23:14 | outer [inner, a] | qualifiers.cpp:23:16:23:20 | inner [a] |
|
||||
| qualifiers.cpp:23:16:23:20 | inner [a] | qualifiers.cpp:23:23:23:23 | a |
|
||||
| qualifiers.cpp:23:23:23:23 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| qualifiers.cpp:27:5:27:9 | ref arg outer [inner, a] | qualifiers.cpp:28:10:28:14 | outer [inner, a] |
|
||||
| qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] | qualifiers.cpp:27:5:27:9 | ref arg outer [inner, a] |
|
||||
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:9:21:9:25 | value |
|
||||
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] |
|
||||
| qualifiers.cpp:28:10:28:14 | outer [inner, a] | qualifiers.cpp:28:16:28:20 | inner [a] |
|
||||
| qualifiers.cpp:28:16:28:20 | inner [a] | qualifiers.cpp:28:23:28:23 | a |
|
||||
| qualifiers.cpp:28:23:28:23 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| qualifiers.cpp:32:17:32:21 | ref arg outer [inner, a] | qualifiers.cpp:33:10:33:14 | outer [inner, a] |
|
||||
| qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] | qualifiers.cpp:32:17:32:21 | ref arg outer [inner, a] |
|
||||
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value |
|
||||
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] |
|
||||
| qualifiers.cpp:33:10:33:14 | outer [inner, a] | qualifiers.cpp:33:16:33:20 | inner [a] |
|
||||
| qualifiers.cpp:33:16:33:20 | inner [a] | qualifiers.cpp:33:23:33:23 | a |
|
||||
| qualifiers.cpp:33:23:33:23 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| qualifiers.cpp:37:19:37:35 | ref arg * ... [a] | qualifiers.cpp:37:26:37:33 | call to getInner [inner post update] [a] |
|
||||
| qualifiers.cpp:37:20:37:24 | ref arg outer [inner, a] | qualifiers.cpp:38:10:38:14 | outer [inner, a] |
|
||||
| qualifiers.cpp:37:26:37:33 | call to getInner [inner post update] [a] | qualifiers.cpp:37:20:37:24 | ref arg outer [inner, a] |
|
||||
@@ -521,6 +633,7 @@ edges
|
||||
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:37:19:37:35 | ref arg * ... [a] |
|
||||
| qualifiers.cpp:38:10:38:14 | outer [inner, a] | qualifiers.cpp:38:16:38:20 | inner [a] |
|
||||
| qualifiers.cpp:38:16:38:20 | inner [a] | qualifiers.cpp:38:23:38:23 | a |
|
||||
| qualifiers.cpp:38:23:38:23 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| qualifiers.cpp:42:5:42:40 | ... = ... | qualifiers.cpp:42:6:42:22 | * ... [post update] [a] |
|
||||
| qualifiers.cpp:42:6:42:22 | * ... [post update] [a] | qualifiers.cpp:42:13:42:20 | call to getInner [inner post update] [a] |
|
||||
| qualifiers.cpp:42:7:42:11 | ref arg outer [inner, a] | qualifiers.cpp:43:10:43:14 | outer [inner, a] |
|
||||
@@ -528,12 +641,15 @@ edges
|
||||
| qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:42:5:42:40 | ... = ... |
|
||||
| qualifiers.cpp:43:10:43:14 | outer [inner, a] | qualifiers.cpp:43:16:43:20 | inner [a] |
|
||||
| qualifiers.cpp:43:16:43:20 | inner [a] | qualifiers.cpp:43:23:43:23 | a |
|
||||
| qualifiers.cpp:43:23:43:23 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| qualifiers.cpp:47:5:47:42 | ... = ... | qualifiers.cpp:47:15:47:22 | call to getInner [post update] [a] |
|
||||
| qualifiers.cpp:47:6:47:11 | ref arg & ... [inner, a] | qualifiers.cpp:48:10:48:14 | outer [inner, a] |
|
||||
| qualifiers.cpp:47:15:47:22 | call to getInner [post update] [a] | qualifiers.cpp:47:6:47:11 | ref arg & ... [inner, a] |
|
||||
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:47:5:47:42 | ... = ... |
|
||||
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | qualifiers.cpp:48:16:48:20 | inner [a] |
|
||||
| qualifiers.cpp:48:16:48:20 | inner [a] | qualifiers.cpp:48:23:48:23 | a |
|
||||
| qualifiers.cpp:48:23:48:23 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| realistic.cpp:41:17:41:17 | o | realistic.cpp:41:17:41:17 | o |
|
||||
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, userInput, bufferLen] | realistic.cpp:61:21:61:23 | foo [bar, baz, userInput, bufferLen] |
|
||||
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, bufferLen] | realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:53:9:53:66 | ... = ... | realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] |
|
||||
@@ -542,10 +658,19 @@ edges
|
||||
| realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] | realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] |
|
||||
| realistic.cpp:53:55:53:64 | call to user_input | realistic.cpp:53:9:53:66 | ... = ... |
|
||||
| realistic.cpp:61:21:61:23 | foo [bar, baz, userInput, bufferLen] | realistic.cpp:61:25:61:27 | bar [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:21:61:23 | foo [post update] [bar, baz, userInput, bufferLen] | realistic.cpp:61:21:61:23 | foo [bar, baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, bufferLen] | realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] |
|
||||
| realistic.cpp:61:21:61:30 | access to array [post update] [baz, userInput, bufferLen] | realistic.cpp:61:25:61:27 | bar [inner post update] [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:25:61:27 | bar [baz, userInput, bufferLen] | realistic.cpp:61:21:61:30 | access to array [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:25:61:27 | bar [inner post update] [baz, userInput, bufferLen] | realistic.cpp:61:21:61:23 | foo [post update] [bar, baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:32:61:34 | baz [post update] [userInput, bufferLen] | realistic.cpp:61:21:61:30 | access to array [post update] [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | realistic.cpp:61:37:61:45 | userInput [bufferLen] |
|
||||
| realistic.cpp:61:37:61:45 | userInput [bufferLen] | realistic.cpp:61:47:61:55 | bufferLen |
|
||||
| realistic.cpp:61:37:61:45 | userInput [bufferLen] | realistic.cpp:61:47:61:55 | bufferLen |
|
||||
| realistic.cpp:61:37:61:45 | userInput [post update] [bufferLen] | realistic.cpp:61:32:61:34 | baz [post update] [userInput, bufferLen] |
|
||||
| realistic.cpp:61:47:61:55 | bufferLen | realistic.cpp:41:17:41:17 | o |
|
||||
| realistic.cpp:61:47:61:55 | bufferLen | realistic.cpp:61:47:61:55 | ref arg bufferLen |
|
||||
| realistic.cpp:61:47:61:55 | ref arg bufferLen | realistic.cpp:61:37:61:45 | userInput [post update] [bufferLen] |
|
||||
| simple.cpp:18:9:18:9 | this [a_] | simple.cpp:18:22:18:23 | this [a_] |
|
||||
| simple.cpp:18:22:18:23 | this [a_] | simple.cpp:18:22:18:23 | a_ |
|
||||
| simple.cpp:19:9:19:9 | this [b_] | simple.cpp:19:22:19:23 | this [b_] |
|
||||
@@ -593,14 +718,28 @@ edges
|
||||
| simple.cpp:92:5:92:22 | ... = ... | simple.cpp:92:5:92:5 | a [post update] [i] |
|
||||
| simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | ... = ... |
|
||||
| simple.cpp:94:10:94:11 | a2 [i] | simple.cpp:94:13:94:13 | i |
|
||||
| struct_init.c:14:24:14:25 | ab [a] | struct_init.c:14:24:14:25 | ab [a] |
|
||||
| struct_init.c:14:24:14:25 | ab [a] | struct_init.c:15:8:15:9 | ab [a] |
|
||||
| struct_init.c:15:8:15:9 | ab [a] | struct_init.c:15:12:15:12 | a |
|
||||
| struct_init.c:15:8:15:9 | ab [a] | struct_init.c:15:12:15:12 | a |
|
||||
| struct_init.c:15:8:15:9 | ab [post update] [a] | struct_init.c:14:24:14:25 | ab [a] |
|
||||
| struct_init.c:15:12:15:12 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| struct_init.c:15:12:15:12 | a | struct_init.c:15:12:15:12 | ref arg a |
|
||||
| struct_init.c:15:12:15:12 | ref arg a | struct_init.c:15:8:15:9 | ab [post update] [a] |
|
||||
| struct_init.c:20:17:20:36 | {...} [a] | struct_init.c:22:8:22:9 | ab [a] |
|
||||
| struct_init.c:20:17:20:36 | {...} [a] | struct_init.c:24:10:24:12 | & ... [a] |
|
||||
| struct_init.c:20:17:20:36 | {...} [a] | struct_init.c:28:5:28:7 | & ... [a] |
|
||||
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:20:17:20:36 | {...} [a] |
|
||||
| struct_init.c:22:8:22:9 | ab [a] | struct_init.c:22:11:22:11 | a |
|
||||
| struct_init.c:22:8:22:9 | ab [a] | struct_init.c:22:11:22:11 | a |
|
||||
| struct_init.c:22:8:22:9 | ab [post update] [a] | struct_init.c:24:10:24:12 | & ... [a] |
|
||||
| struct_init.c:22:8:22:9 | ab [post update] [a] | struct_init.c:28:5:28:7 | & ... [a] |
|
||||
| struct_init.c:22:11:22:11 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| struct_init.c:22:11:22:11 | a | struct_init.c:22:11:22:11 | ref arg a |
|
||||
| struct_init.c:22:11:22:11 | ref arg a | struct_init.c:22:8:22:9 | ab [post update] [a] |
|
||||
| struct_init.c:24:10:24:12 | & ... [a] | struct_init.c:14:24:14:25 | ab [a] |
|
||||
| struct_init.c:24:10:24:12 | & ... [a] | struct_init.c:24:10:24:12 | ref arg & ... [a] |
|
||||
| struct_init.c:24:10:24:12 | ref arg & ... [a] | struct_init.c:28:5:28:7 | & ... [a] |
|
||||
| struct_init.c:26:23:29:3 | {...} [nestedAB, a] | struct_init.c:31:8:31:12 | outer [nestedAB, a] |
|
||||
| struct_init.c:26:23:29:3 | {...} [nestedAB, a] | struct_init.c:36:11:36:15 | outer [nestedAB, a] |
|
||||
| struct_init.c:26:23:29:3 | {...} [pointerAB, a] | struct_init.c:33:8:33:12 | outer [pointerAB, a] |
|
||||
@@ -608,9 +747,16 @@ edges
|
||||
| struct_init.c:27:7:27:16 | call to user_input | struct_init.c:27:5:27:23 | {...} [a] |
|
||||
| struct_init.c:28:5:28:7 | & ... [a] | struct_init.c:26:23:29:3 | {...} [pointerAB, a] |
|
||||
| struct_init.c:31:8:31:12 | outer [nestedAB, a] | struct_init.c:31:14:31:21 | nestedAB [a] |
|
||||
| struct_init.c:31:8:31:12 | outer [post update] [nestedAB, a] | struct_init.c:36:11:36:15 | outer [nestedAB, a] |
|
||||
| struct_init.c:31:14:31:21 | nestedAB [a] | struct_init.c:31:23:31:23 | a |
|
||||
| struct_init.c:31:14:31:21 | nestedAB [a] | struct_init.c:31:23:31:23 | a |
|
||||
| struct_init.c:31:14:31:21 | nestedAB [post update] [a] | struct_init.c:31:8:31:12 | outer [post update] [nestedAB, a] |
|
||||
| struct_init.c:31:23:31:23 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| struct_init.c:31:23:31:23 | a | struct_init.c:31:23:31:23 | ref arg a |
|
||||
| struct_init.c:31:23:31:23 | ref arg a | struct_init.c:31:14:31:21 | nestedAB [post update] [a] |
|
||||
| struct_init.c:33:8:33:12 | outer [pointerAB, a] | struct_init.c:33:14:33:22 | pointerAB [a] |
|
||||
| struct_init.c:33:14:33:22 | pointerAB [a] | struct_init.c:33:25:33:25 | a |
|
||||
| struct_init.c:33:25:33:25 | a | realistic.cpp:41:17:41:17 | o |
|
||||
| struct_init.c:36:10:36:24 | & ... [a] | struct_init.c:14:24:14:25 | ab [a] |
|
||||
| struct_init.c:36:11:36:15 | outer [nestedAB, a] | struct_init.c:36:17:36:24 | nestedAB [a] |
|
||||
| struct_init.c:36:17:36:24 | nestedAB [a] | struct_init.c:36:10:36:24 | & ... [a] |
|
||||
@@ -674,12 +820,14 @@ nodes
|
||||
| A.cpp:107:16:107:16 | a | semmle.label | a |
|
||||
| A.cpp:120:12:120:13 | c1 [a] | semmle.label | c1 [a] |
|
||||
| A.cpp:120:16:120:16 | a | semmle.label | a |
|
||||
| A.cpp:124:14:124:14 | b [c] | semmle.label | b [c] |
|
||||
| A.cpp:126:5:126:5 | ref arg b [c] | semmle.label | ref arg b [c] |
|
||||
| A.cpp:126:12:126:18 | new | semmle.label | new |
|
||||
| A.cpp:131:8:131:8 | ref arg b [c] | semmle.label | ref arg b [c] |
|
||||
| A.cpp:132:10:132:10 | b [c] | semmle.label | b [c] |
|
||||
| A.cpp:132:13:132:13 | c | semmle.label | c |
|
||||
| A.cpp:140:13:140:13 | b | semmle.label | b |
|
||||
| A.cpp:140:13:140:13 | b [c] | semmle.label | b [c] |
|
||||
| A.cpp:142:7:142:7 | b [post update] [c] | semmle.label | b [post update] [c] |
|
||||
| A.cpp:142:7:142:20 | ... = ... | semmle.label | ... = ... |
|
||||
| A.cpp:142:14:142:20 | new | semmle.label | new |
|
||||
@@ -695,8 +843,12 @@ nodes
|
||||
| A.cpp:151:12:151:24 | call to D [b] | semmle.label | call to D [b] |
|
||||
| A.cpp:151:18:151:18 | b | semmle.label | b |
|
||||
| A.cpp:151:18:151:18 | ref arg b [c] | semmle.label | ref arg b [c] |
|
||||
| A.cpp:152:10:152:10 | d [b, c] | semmle.label | d [b, c] |
|
||||
| A.cpp:152:10:152:10 | d [b] | semmle.label | d [b] |
|
||||
| A.cpp:152:10:152:10 | d [post update] [b, c] | semmle.label | d [post update] [b, c] |
|
||||
| A.cpp:152:13:152:13 | b | semmle.label | b |
|
||||
| A.cpp:152:13:152:13 | b [c] | semmle.label | b [c] |
|
||||
| A.cpp:152:13:152:13 | ref arg b [c] | semmle.label | ref arg b [c] |
|
||||
| A.cpp:153:10:153:10 | d [b, c] | semmle.label | d [b, c] |
|
||||
| A.cpp:153:13:153:13 | b [c] | semmle.label | b [c] |
|
||||
| A.cpp:153:16:153:16 | c | semmle.label | c |
|
||||
@@ -710,15 +862,24 @@ nodes
|
||||
| A.cpp:162:18:162:40 | call to MyList [next, next, head] | semmle.label | call to MyList [next, next, head] |
|
||||
| A.cpp:162:38:162:39 | l2 [next, head] | semmle.label | l2 [next, head] |
|
||||
| A.cpp:165:10:165:11 | l3 [next, next, head] | semmle.label | l3 [next, next, head] |
|
||||
| A.cpp:165:10:165:11 | l3 [post update] [next, next, head] | semmle.label | l3 [post update] [next, next, head] |
|
||||
| A.cpp:165:14:165:17 | next [next, head] | semmle.label | next [next, head] |
|
||||
| A.cpp:165:14:165:17 | next [post update] [next, head] | semmle.label | next [post update] [next, head] |
|
||||
| A.cpp:165:20:165:23 | next [head] | semmle.label | next [head] |
|
||||
| A.cpp:165:20:165:23 | next [post update] [head] | semmle.label | next [post update] [head] |
|
||||
| A.cpp:165:26:165:29 | head | semmle.label | head |
|
||||
| A.cpp:165:26:165:29 | head | semmle.label | head |
|
||||
| A.cpp:165:26:165:29 | ref arg head | semmle.label | ref arg head |
|
||||
| A.cpp:167:44:167:44 | l [next, head] | semmle.label | l [next, head] |
|
||||
| A.cpp:167:44:167:44 | l [next, next, head] | semmle.label | l [next, next, head] |
|
||||
| A.cpp:167:47:167:50 | next [head] | semmle.label | next [head] |
|
||||
| A.cpp:167:47:167:50 | next [next, head] | semmle.label | next [next, head] |
|
||||
| A.cpp:169:12:169:12 | l [head] | semmle.label | l [head] |
|
||||
| A.cpp:169:15:169:18 | head | semmle.label | head |
|
||||
| A.cpp:173:26:173:26 | o | semmle.label | o |
|
||||
| A.cpp:173:26:173:26 | o | semmle.label | o |
|
||||
| A.cpp:173:26:173:26 | o [c] | semmle.label | o [c] |
|
||||
| A.cpp:173:26:173:26 | o [c] | semmle.label | o [c] |
|
||||
| A.cpp:181:15:181:21 | newHead | semmle.label | newHead |
|
||||
| A.cpp:181:32:181:35 | next [head] | semmle.label | next [head] |
|
||||
| A.cpp:181:32:181:35 | next [next, head] | semmle.label | next [next, head] |
|
||||
@@ -829,6 +990,7 @@ nodes
|
||||
| E.cpp:32:10:32:10 | b [buffer] | semmle.label | b [buffer] |
|
||||
| E.cpp:32:13:32:18 | buffer | semmle.label | buffer |
|
||||
| E.cpp:33:18:33:19 | & ... [data, buffer] | semmle.label | & ... [data, buffer] |
|
||||
| aliasing.cpp:8:23:8:23 | s [m1] | semmle.label | s [m1] |
|
||||
| aliasing.cpp:9:3:9:3 | s [post update] [m1] | semmle.label | s [post update] [m1] |
|
||||
| aliasing.cpp:9:3:9:22 | ... = ... | semmle.label | ... = ... |
|
||||
| aliasing.cpp:9:11:9:20 | call to user_input | semmle.label | call to user_input |
|
||||
@@ -854,6 +1016,7 @@ nodes
|
||||
| aliasing.cpp:93:8:93:8 | w [s, m1] | semmle.label | w [s, m1] |
|
||||
| aliasing.cpp:93:10:93:10 | s [m1] | semmle.label | s [m1] |
|
||||
| aliasing.cpp:93:12:93:13 | m1 | semmle.label | m1 |
|
||||
| aliasing.cpp:105:23:105:24 | pa | semmle.label | pa |
|
||||
| aliasing.cpp:106:4:106:5 | pa [inner post update] | semmle.label | pa [inner post update] |
|
||||
| aliasing.cpp:106:9:106:18 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:158:15:158:15 | s [post update] [data] | semmle.label | s [post update] [data] |
|
||||
@@ -902,10 +1065,16 @@ nodes
|
||||
| arrays.cpp:36:12:36:14 | arr [inner post update] [data] | semmle.label | arr [inner post update] [data] |
|
||||
| arrays.cpp:36:26:36:35 | call to user_input | semmle.label | call to user_input |
|
||||
| arrays.cpp:37:8:37:8 | o [nested, arr, data] | semmle.label | o [nested, arr, data] |
|
||||
| arrays.cpp:37:8:37:8 | o [post update] [nested, arr, data] | semmle.label | o [post update] [nested, arr, data] |
|
||||
| arrays.cpp:37:8:37:22 | access to array [data] | semmle.label | access to array [data] |
|
||||
| arrays.cpp:37:8:37:22 | access to array [post update] [data] | semmle.label | access to array [post update] [data] |
|
||||
| arrays.cpp:37:10:37:15 | nested [arr, data] | semmle.label | nested [arr, data] |
|
||||
| arrays.cpp:37:10:37:15 | nested [post update] [arr, data] | semmle.label | nested [post update] [arr, data] |
|
||||
| arrays.cpp:37:17:37:19 | arr [data] | semmle.label | arr [data] |
|
||||
| arrays.cpp:37:17:37:19 | arr [inner post update] [data] | semmle.label | arr [inner post update] [data] |
|
||||
| arrays.cpp:37:24:37:27 | data | semmle.label | data |
|
||||
| arrays.cpp:37:24:37:27 | data | semmle.label | data |
|
||||
| arrays.cpp:37:24:37:27 | ref arg data | semmle.label | ref arg data |
|
||||
| arrays.cpp:38:8:38:8 | o [nested, arr, data] | semmle.label | o [nested, arr, data] |
|
||||
| arrays.cpp:38:8:38:22 | access to array [data] | semmle.label | access to array [data] |
|
||||
| arrays.cpp:38:10:38:15 | nested [arr, data] | semmle.label | nested [arr, data] |
|
||||
@@ -918,15 +1087,22 @@ nodes
|
||||
| arrays.cpp:42:15:42:17 | arr [inner post update] [data] | semmle.label | arr [inner post update] [data] |
|
||||
| arrays.cpp:42:29:42:38 | call to user_input | semmle.label | call to user_input |
|
||||
| arrays.cpp:43:8:43:8 | o [indirect, arr, data] | semmle.label | o [indirect, arr, data] |
|
||||
| arrays.cpp:43:8:43:8 | o [post update] [indirect, arr, data] | semmle.label | o [post update] [indirect, arr, data] |
|
||||
| arrays.cpp:43:8:43:25 | access to array [data] | semmle.label | access to array [data] |
|
||||
| arrays.cpp:43:8:43:25 | access to array [post update] [data] | semmle.label | access to array [post update] [data] |
|
||||
| arrays.cpp:43:10:43:17 | indirect [arr, data] | semmle.label | indirect [arr, data] |
|
||||
| arrays.cpp:43:10:43:17 | indirect [post update] [arr, data] | semmle.label | indirect [post update] [arr, data] |
|
||||
| arrays.cpp:43:20:43:22 | arr [data] | semmle.label | arr [data] |
|
||||
| arrays.cpp:43:20:43:22 | arr [inner post update] [data] | semmle.label | arr [inner post update] [data] |
|
||||
| arrays.cpp:43:27:43:30 | data | semmle.label | data |
|
||||
| arrays.cpp:43:27:43:30 | data | semmle.label | data |
|
||||
| arrays.cpp:43:27:43:30 | ref arg data | semmle.label | ref arg data |
|
||||
| arrays.cpp:44:8:44:8 | o [indirect, arr, data] | semmle.label | o [indirect, arr, data] |
|
||||
| arrays.cpp:44:8:44:25 | access to array [data] | semmle.label | access to array [data] |
|
||||
| arrays.cpp:44:10:44:17 | indirect [arr, data] | semmle.label | indirect [arr, data] |
|
||||
| arrays.cpp:44:20:44:22 | arr [data] | semmle.label | arr [data] |
|
||||
| arrays.cpp:44:27:44:30 | data | semmle.label | data |
|
||||
| by_reference.cpp:11:39:11:39 | s [a] | semmle.label | s [a] |
|
||||
| by_reference.cpp:11:48:11:52 | value | semmle.label | value |
|
||||
| by_reference.cpp:12:5:12:5 | s [post update] [a] | semmle.label | s [post update] [a] |
|
||||
| by_reference.cpp:12:5:12:16 | ... = ... | semmle.label | ... = ... |
|
||||
@@ -967,6 +1143,7 @@ nodes
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | semmle.label | call to nonMemberGetA |
|
||||
| by_reference.cpp:69:22:69:23 | & ... [a] | semmle.label | & ... [a] |
|
||||
| by_reference.cpp:83:31:83:35 | inner [a] | semmle.label | inner [a] |
|
||||
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | semmle.label | inner [post update] [a] |
|
||||
| by_reference.cpp:84:3:84:25 | ... = ... | semmle.label | ... = ... |
|
||||
| by_reference.cpp:84:14:84:23 | call to user_input | semmle.label | call to user_input |
|
||||
@@ -974,6 +1151,7 @@ nodes
|
||||
| by_reference.cpp:88:3:88:7 | inner [post update] [a] | semmle.label | inner [post update] [a] |
|
||||
| by_reference.cpp:88:3:88:24 | ... = ... | semmle.label | ... = ... |
|
||||
| by_reference.cpp:88:13:88:22 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:91:25:91:26 | pa | semmle.label | pa |
|
||||
| by_reference.cpp:92:4:92:5 | pa [inner post update] | semmle.label | pa [inner post update] |
|
||||
| by_reference.cpp:92:9:92:18 | call to user_input | semmle.label | call to user_input |
|
||||
| by_reference.cpp:95:25:95:26 | pa | semmle.label | pa |
|
||||
@@ -1141,6 +1319,7 @@ nodes
|
||||
| qualifiers.cpp:9:21:9:25 | value | semmle.label | value |
|
||||
| qualifiers.cpp:9:30:9:33 | this [post update] [a] | semmle.label | this [post update] [a] |
|
||||
| qualifiers.cpp:9:30:9:44 | ... = ... | semmle.label | ... = ... |
|
||||
| qualifiers.cpp:12:27:12:31 | inner [a] | semmle.label | inner [a] |
|
||||
| qualifiers.cpp:12:40:12:44 | value | semmle.label | value |
|
||||
| qualifiers.cpp:12:49:12:53 | inner [post update] [a] | semmle.label | inner [post update] [a] |
|
||||
| qualifiers.cpp:12:49:12:64 | ... = ... | semmle.label | ... = ... |
|
||||
@@ -1189,6 +1368,8 @@ nodes
|
||||
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | semmle.label | outer [inner, a] |
|
||||
| qualifiers.cpp:48:16:48:20 | inner [a] | semmle.label | inner [a] |
|
||||
| qualifiers.cpp:48:23:48:23 | a | semmle.label | a |
|
||||
| realistic.cpp:41:17:41:17 | o | semmle.label | o |
|
||||
| realistic.cpp:41:17:41:17 | o | semmle.label | o |
|
||||
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, userInput, bufferLen] | semmle.label | foo [post update] [bar, baz, userInput, bufferLen] |
|
||||
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, bufferLen] | semmle.label | access to array [post update] [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:53:9:53:66 | ... = ... | semmle.label | ... = ... |
|
||||
@@ -1197,11 +1378,18 @@ nodes
|
||||
| realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] | semmle.label | userInput [post update] [bufferLen] |
|
||||
| realistic.cpp:53:55:53:64 | call to user_input | semmle.label | call to user_input |
|
||||
| realistic.cpp:61:21:61:23 | foo [bar, baz, userInput, bufferLen] | semmle.label | foo [bar, baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:21:61:23 | foo [post update] [bar, baz, userInput, bufferLen] | semmle.label | foo [post update] [bar, baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, bufferLen] | semmle.label | access to array [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:21:61:30 | access to array [post update] [baz, userInput, bufferLen] | semmle.label | access to array [post update] [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:25:61:27 | bar [baz, userInput, bufferLen] | semmle.label | bar [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:25:61:27 | bar [inner post update] [baz, userInput, bufferLen] | semmle.label | bar [inner post update] [baz, userInput, bufferLen] |
|
||||
| realistic.cpp:61:32:61:34 | baz [post update] [userInput, bufferLen] | semmle.label | baz [post update] [userInput, bufferLen] |
|
||||
| realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | semmle.label | baz [userInput, bufferLen] |
|
||||
| realistic.cpp:61:37:61:45 | userInput [bufferLen] | semmle.label | userInput [bufferLen] |
|
||||
| realistic.cpp:61:37:61:45 | userInput [post update] [bufferLen] | semmle.label | userInput [post update] [bufferLen] |
|
||||
| realistic.cpp:61:47:61:55 | bufferLen | semmle.label | bufferLen |
|
||||
| realistic.cpp:61:47:61:55 | bufferLen | semmle.label | bufferLen |
|
||||
| realistic.cpp:61:47:61:55 | ref arg bufferLen | semmle.label | ref arg bufferLen |
|
||||
| simple.cpp:18:9:18:9 | this [a_] | semmle.label | this [a_] |
|
||||
| simple.cpp:18:22:18:23 | a_ | semmle.label | a_ |
|
||||
| simple.cpp:18:22:18:23 | this [a_] | semmle.label | this [a_] |
|
||||
@@ -1253,21 +1441,33 @@ nodes
|
||||
| simple.cpp:94:10:94:11 | a2 [i] | semmle.label | a2 [i] |
|
||||
| simple.cpp:94:13:94:13 | i | semmle.label | i |
|
||||
| struct_init.c:14:24:14:25 | ab [a] | semmle.label | ab [a] |
|
||||
| struct_init.c:14:24:14:25 | ab [a] | semmle.label | ab [a] |
|
||||
| struct_init.c:15:8:15:9 | ab [a] | semmle.label | ab [a] |
|
||||
| struct_init.c:15:8:15:9 | ab [post update] [a] | semmle.label | ab [post update] [a] |
|
||||
| struct_init.c:15:12:15:12 | a | semmle.label | a |
|
||||
| struct_init.c:15:12:15:12 | a | semmle.label | a |
|
||||
| struct_init.c:15:12:15:12 | ref arg a | semmle.label | ref arg a |
|
||||
| struct_init.c:20:17:20:36 | {...} [a] | semmle.label | {...} [a] |
|
||||
| struct_init.c:20:20:20:29 | call to user_input | semmle.label | call to user_input |
|
||||
| struct_init.c:22:8:22:9 | ab [a] | semmle.label | ab [a] |
|
||||
| struct_init.c:22:8:22:9 | ab [post update] [a] | semmle.label | ab [post update] [a] |
|
||||
| struct_init.c:22:11:22:11 | a | semmle.label | a |
|
||||
| struct_init.c:22:11:22:11 | a | semmle.label | a |
|
||||
| struct_init.c:22:11:22:11 | ref arg a | semmle.label | ref arg a |
|
||||
| struct_init.c:24:10:24:12 | & ... [a] | semmle.label | & ... [a] |
|
||||
| struct_init.c:24:10:24:12 | ref arg & ... [a] | semmle.label | ref arg & ... [a] |
|
||||
| struct_init.c:26:23:29:3 | {...} [nestedAB, a] | semmle.label | {...} [nestedAB, a] |
|
||||
| struct_init.c:26:23:29:3 | {...} [pointerAB, a] | semmle.label | {...} [pointerAB, a] |
|
||||
| struct_init.c:27:5:27:23 | {...} [a] | semmle.label | {...} [a] |
|
||||
| struct_init.c:27:7:27:16 | call to user_input | semmle.label | call to user_input |
|
||||
| struct_init.c:28:5:28:7 | & ... [a] | semmle.label | & ... [a] |
|
||||
| struct_init.c:31:8:31:12 | outer [nestedAB, a] | semmle.label | outer [nestedAB, a] |
|
||||
| struct_init.c:31:8:31:12 | outer [post update] [nestedAB, a] | semmle.label | outer [post update] [nestedAB, a] |
|
||||
| struct_init.c:31:14:31:21 | nestedAB [a] | semmle.label | nestedAB [a] |
|
||||
| struct_init.c:31:14:31:21 | nestedAB [post update] [a] | semmle.label | nestedAB [post update] [a] |
|
||||
| struct_init.c:31:23:31:23 | a | semmle.label | a |
|
||||
| struct_init.c:31:23:31:23 | a | semmle.label | a |
|
||||
| struct_init.c:31:23:31:23 | ref arg a | semmle.label | ref arg a |
|
||||
| struct_init.c:33:8:33:12 | outer [pointerAB, a] | semmle.label | outer [pointerAB, a] |
|
||||
| struct_init.c:33:14:33:22 | pointerAB [a] | semmle.label | pointerAB [a] |
|
||||
| struct_init.c:33:25:33:25 | a | semmle.label | a |
|
||||
@@ -1293,9 +1493,11 @@ subpaths
|
||||
| A.cpp:90:15:90:15 | c | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:25 | this [post update] [c] | A.cpp:90:7:90:8 | ref arg b2 [c] |
|
||||
| A.cpp:126:12:126:18 | new | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:25 | this [post update] [c] | A.cpp:126:5:126:5 | ref arg b [c] |
|
||||
| A.cpp:151:18:151:18 | b | A.cpp:140:13:140:13 | b | A.cpp:143:7:143:10 | this [post update] [b] | A.cpp:151:12:151:24 | call to D [b] |
|
||||
| A.cpp:152:13:152:13 | b [c] | A.cpp:173:26:173:26 | o [c] | A.cpp:173:26:173:26 | o [c] | A.cpp:152:13:152:13 | ref arg b [c] |
|
||||
| A.cpp:160:29:160:29 | b | A.cpp:181:15:181:21 | newHead | A.cpp:183:7:183:10 | this [post update] [head] | A.cpp:160:18:160:60 | call to MyList [head] |
|
||||
| A.cpp:161:38:161:39 | l1 [head] | A.cpp:181:32:181:35 | next [head] | A.cpp:184:7:184:10 | this [post update] [next, head] | A.cpp:161:18:161:40 | call to MyList [next, head] |
|
||||
| A.cpp:162:38:162:39 | l2 [next, head] | A.cpp:181:32:181:35 | next [next, head] | A.cpp:184:7:184:10 | this [post update] [next, next, head] | A.cpp:162:18:162:40 | call to MyList [next, next, head] |
|
||||
| A.cpp:165:26:165:29 | head | A.cpp:173:26:173:26 | o | A.cpp:173:26:173:26 | o | A.cpp:165:26:165:29 | ref arg head |
|
||||
| B.cpp:7:25:7:25 | e | B.cpp:33:16:33:17 | e1 | B.cpp:35:7:35:10 | this [post update] [elem1] | B.cpp:7:16:7:35 | call to Box1 [elem1] |
|
||||
| B.cpp:8:25:8:26 | b1 [elem1] | B.cpp:44:16:44:17 | b1 [elem1] | B.cpp:46:7:46:10 | this [post update] [box1, elem1] | B.cpp:8:16:8:27 | call to Box2 [box1, elem1] |
|
||||
| B.cpp:16:37:16:37 | e | B.cpp:33:26:33:27 | e2 | B.cpp:36:7:36:10 | this [post update] [elem2] | B.cpp:16:16:16:38 | call to Box1 [elem2] |
|
||||
@@ -1304,7 +1506,10 @@ subpaths
|
||||
| D.cpp:22:14:22:20 | call to getBox1 [elem] | D.cpp:10:11:10:17 | this [elem] | D.cpp:10:30:10:33 | elem | D.cpp:22:25:22:31 | call to getElem |
|
||||
| D.cpp:37:21:37:21 | e | D.cpp:11:24:11:24 | e | D.cpp:11:29:11:32 | this [post update] [elem] | D.cpp:37:8:37:10 | ref arg box [elem] |
|
||||
| D.cpp:51:27:51:27 | e | D.cpp:11:24:11:24 | e | D.cpp:11:29:11:32 | this [post update] [elem] | D.cpp:51:8:51:14 | ref arg call to getBox1 [elem] |
|
||||
| arrays.cpp:37:24:37:27 | data | realistic.cpp:41:17:41:17 | o | realistic.cpp:41:17:41:17 | o | arrays.cpp:37:24:37:27 | ref arg data |
|
||||
| arrays.cpp:43:27:43:30 | data | realistic.cpp:41:17:41:17 | o | realistic.cpp:41:17:41:17 | o | arrays.cpp:43:27:43:30 | ref arg data |
|
||||
| by_reference.cpp:20:23:20:27 | value | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:8 | this [post update] [a] | by_reference.cpp:20:5:20:8 | ref arg this [a] |
|
||||
| by_reference.cpp:24:25:24:29 | value | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:11:39:11:39 | s [a] | by_reference.cpp:24:19:24:22 | ref arg this [a] |
|
||||
| by_reference.cpp:24:25:24:29 | value | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:5 | s [post update] [a] | by_reference.cpp:24:19:24:22 | ref arg this [a] |
|
||||
| by_reference.cpp:40:12:40:15 | this [a] | by_reference.cpp:35:9:35:19 | this [a] | by_reference.cpp:36:18:36:18 | a | by_reference.cpp:40:18:40:28 | call to getDirectly |
|
||||
| by_reference.cpp:44:26:44:29 | this [a] | by_reference.cpp:31:46:31:46 | s [a] | by_reference.cpp:32:15:32:15 | a | by_reference.cpp:44:12:44:24 | call to nonMemberGetA |
|
||||
@@ -1314,6 +1519,7 @@ subpaths
|
||||
| by_reference.cpp:57:8:57:8 | s [a] | by_reference.cpp:39:9:39:21 | this [a] | by_reference.cpp:40:18:40:28 | call to getDirectly | by_reference.cpp:57:10:57:22 | call to getIndirectly |
|
||||
| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:23:34:23:38 | value | by_reference.cpp:24:19:24:22 | ref arg this [a] | by_reference.cpp:62:3:62:3 | ref arg s [a] |
|
||||
| by_reference.cpp:63:8:63:8 | s [a] | by_reference.cpp:43:9:43:27 | this [a] | by_reference.cpp:44:12:44:24 | call to nonMemberGetA | by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:11:39:11:39 | s [a] | by_reference.cpp:68:17:68:18 | ref arg & ... [a] |
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:5 | s [post update] [a] | by_reference.cpp:68:17:68:18 | ref arg & ... [a] |
|
||||
| by_reference.cpp:69:22:69:23 | & ... [a] | by_reference.cpp:31:46:31:46 | s [a] | by_reference.cpp:32:15:32:15 | a | by_reference.cpp:69:8:69:20 | call to nonMemberGetA |
|
||||
| complex.cpp:42:16:42:16 | f [a_] | complex.cpp:9:7:9:7 | this [a_] | complex.cpp:9:20:9:21 | a_ | complex.cpp:42:18:42:18 | call to a |
|
||||
@@ -1329,9 +1535,11 @@ subpaths
|
||||
| constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:23:13:23:13 | a | constructors.cpp:23:25:23:29 | constructor init of field a_ [post-this] [a_] | constructors.cpp:36:11:36:37 | call to Foo [a_] |
|
||||
| constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:23:20:23:20 | b | constructors.cpp:23:32:23:36 | constructor init of field b_ [post-this] [b_] | constructors.cpp:36:11:36:37 | call to Foo [b_] |
|
||||
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:9:21:9:25 | value | qualifiers.cpp:9:30:9:33 | this [post update] [a] | qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] |
|
||||
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value | qualifiers.cpp:12:27:12:31 | inner [a] | qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] |
|
||||
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value | qualifiers.cpp:12:49:12:53 | inner [post update] [a] | qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] |
|
||||
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value | qualifiers.cpp:13:29:13:33 | inner [a] | qualifiers.cpp:37:19:37:35 | ref arg * ... [a] |
|
||||
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value | qualifiers.cpp:13:51:13:55 | inner [post update] [a] | qualifiers.cpp:37:19:37:35 | ref arg * ... [a] |
|
||||
| realistic.cpp:61:47:61:55 | bufferLen | realistic.cpp:41:17:41:17 | o | realistic.cpp:41:17:41:17 | o | realistic.cpp:61:47:61:55 | ref arg bufferLen |
|
||||
| simple.cpp:28:10:28:10 | f [a_] | simple.cpp:18:9:18:9 | this [a_] | simple.cpp:18:22:18:23 | a_ | simple.cpp:28:12:28:12 | call to a |
|
||||
| simple.cpp:29:10:29:10 | f [b_] | simple.cpp:19:9:19:9 | this [b_] | simple.cpp:19:22:19:23 | b_ | simple.cpp:29:12:29:12 | call to b |
|
||||
| simple.cpp:39:12:39:21 | call to user_input | simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:25 | this [post update] [a_] | simple.cpp:39:5:39:5 | ref arg f [a_] |
|
||||
@@ -1339,6 +1547,10 @@ subpaths
|
||||
| simple.cpp:41:12:41:21 | call to user_input | simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:25 | this [post update] [a_] | simple.cpp:41:5:41:5 | ref arg h [a_] |
|
||||
| simple.cpp:42:12:42:21 | call to user_input | simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:25 | this [post update] [b_] | simple.cpp:42:5:42:5 | ref arg h [b_] |
|
||||
| simple.cpp:84:14:84:20 | this [f2, f1] | simple.cpp:78:9:78:15 | this [f2, f1] | simple.cpp:79:19:79:20 | f1 | simple.cpp:84:14:84:20 | call to getf2f1 |
|
||||
| struct_init.c:15:12:15:12 | a | realistic.cpp:41:17:41:17 | o | realistic.cpp:41:17:41:17 | o | struct_init.c:15:12:15:12 | ref arg a |
|
||||
| struct_init.c:22:11:22:11 | a | realistic.cpp:41:17:41:17 | o | realistic.cpp:41:17:41:17 | o | struct_init.c:22:11:22:11 | ref arg a |
|
||||
| struct_init.c:24:10:24:12 | & ... [a] | struct_init.c:14:24:14:25 | ab [a] | struct_init.c:14:24:14:25 | ab [a] | struct_init.c:24:10:24:12 | ref arg & ... [a] |
|
||||
| struct_init.c:31:23:31:23 | a | realistic.cpp:41:17:41:17 | o | realistic.cpp:41:17:41:17 | o | struct_init.c:31:23:31:23 | ref arg a |
|
||||
#select
|
||||
| A.cpp:43:10:43:12 | & ... | A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... | & ... flows from $@ | A.cpp:41:15:41:21 | new | new |
|
||||
| A.cpp:49:13:49:13 | c | A.cpp:47:12:47:18 | new | A.cpp:49:13:49:13 | c | c flows from $@ | A.cpp:47:12:47:18 | new | new |
|
||||
|
||||
@@ -12,7 +12,7 @@ struct Outer {
|
||||
};
|
||||
|
||||
void absink(struct AB *ab) {
|
||||
sink(ab->a); //$ ast,ir=20:20 ast,ir=27:7 ast=40:20 MISSING: ir
|
||||
sink(ab->a); //$ ast,ir=20:20 ast,ir=27:7 ast,ir=40:20
|
||||
sink(ab->b); // no flow
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ int struct_init(void) {
|
||||
|
||||
sink(outer.nestedAB.a); //$ ast,ir
|
||||
sink(outer.nestedAB.b); // no flow
|
||||
sink(outer.pointerAB->a); //$ ast MISSING: ir
|
||||
sink(outer.pointerAB->a); //$ ast,ir
|
||||
sink(outer.pointerAB->b); // no flow
|
||||
|
||||
absink(&outer.nestedAB);
|
||||
|
||||
@@ -21,9 +21,9 @@ void test_unique_ptr_struct() {
|
||||
std::unique_ptr<A> p1(new A{source(), 0});
|
||||
std::unique_ptr<A> p2 = std::make_unique<A>(source(), 0);
|
||||
|
||||
sink(p1->x); // $ ir MISSING: ast
|
||||
sink(p1->x); // $ MISSING: ast,ir
|
||||
sink(p1->y);
|
||||
sink(p2->x); // $ ir=22:46 MISSING: ast
|
||||
sink(p2->x); // $ MISSING: ast,ir=22:46
|
||||
sink(p2->y);
|
||||
}
|
||||
|
||||
|
||||
@@ -299,12 +299,15 @@
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
|
||||
| format.cpp:16:21:16:21 | s | format.cpp:16:21:16:21 | s | |
|
||||
| format.cpp:16:21:16:21 | s | format.cpp:22:22:22:22 | s | |
|
||||
| format.cpp:16:31:16:31 | n | format.cpp:22:25:22:25 | n | |
|
||||
| format.cpp:16:46:16:51 | format | format.cpp:16:46:16:51 | format | |
|
||||
| format.cpp:16:46:16:51 | format | format.cpp:22:28:22:33 | format | |
|
||||
| format.cpp:20:10:20:13 | args | format.cpp:22:36:22:39 | args | |
|
||||
| format.cpp:22:12:22:20 | call to vsnprintf | format.cpp:22:3:22:40 | ... = ... | |
|
||||
| format.cpp:22:12:22:20 | call to vsnprintf | format.cpp:25:9:25:14 | result | |
|
||||
| format.cpp:22:22:22:22 | ref arg s | format.cpp:16:21:16:21 | s | |
|
||||
| format.cpp:50:21:50:24 | {...} | format.cpp:51:17:51:22 | buffer | |
|
||||
| format.cpp:50:21:50:24 | {...} | format.cpp:52:8:52:13 | buffer | |
|
||||
| format.cpp:50:23:50:23 | 0 | format.cpp:50:21:50:24 | {...} | TAINT |
|
||||
@@ -3344,7 +3347,9 @@
|
||||
| smart_pointer.cpp:93:8:93:8 | ref arg q | smart_pointer.cpp:94:8:94:8 | q | |
|
||||
| smart_pointer.cpp:94:8:94:8 | q | smart_pointer.cpp:94:9:94:9 | call to operator-> | |
|
||||
| smart_pointer.cpp:94:8:94:8 | ref arg q | smart_pointer.cpp:86:67:86:67 | q | |
|
||||
| smart_pointer.cpp:97:17:97:18 | pa | smart_pointer.cpp:97:17:97:18 | pa | |
|
||||
| smart_pointer.cpp:97:17:97:18 | pa | smart_pointer.cpp:98:5:98:6 | pa | |
|
||||
| smart_pointer.cpp:98:5:98:6 | pa [post update] | smart_pointer.cpp:97:17:97:18 | pa | |
|
||||
| smart_pointer.cpp:98:5:98:20 | ... = ... | smart_pointer.cpp:98:9:98:9 | x [post update] | |
|
||||
| smart_pointer.cpp:98:13:98:18 | call to source | smart_pointer.cpp:98:5:98:20 | ... = ... | |
|
||||
| smart_pointer.cpp:102:25:102:50 | call to unique_ptr | smart_pointer.cpp:103:11:103:11 | p | |
|
||||
@@ -5923,11 +5928,13 @@
|
||||
| taint.cpp:172:10:172:15 | buffer | taint.cpp:172:10:172:15 | ref arg buffer | TAINT |
|
||||
| taint.cpp:172:10:172:15 | ref arg buffer | taint.cpp:173:8:173:13 | buffer | |
|
||||
| taint.cpp:172:18:172:24 | tainted | taint.cpp:172:10:172:15 | ref arg buffer | TAINT |
|
||||
| taint.cpp:180:19:180:19 | p | taint.cpp:180:19:180:19 | p | |
|
||||
| taint.cpp:180:19:180:19 | p | taint.cpp:181:9:181:9 | p | |
|
||||
| taint.cpp:181:9:181:9 | p | taint.cpp:181:8:181:9 | * ... | TAINT |
|
||||
| taint.cpp:185:11:185:16 | call to source | taint.cpp:186:11:186:11 | x | |
|
||||
| taint.cpp:186:10:186:11 | ref arg & ... | taint.cpp:186:11:186:11 | x [inner post update] | |
|
||||
| taint.cpp:186:11:186:11 | x | taint.cpp:186:10:186:11 | & ... | |
|
||||
| taint.cpp:192:23:192:28 | source | taint.cpp:192:23:192:28 | source | |
|
||||
| taint.cpp:192:23:192:28 | source | taint.cpp:194:13:194:18 | source | |
|
||||
| taint.cpp:193:6:193:6 | x | taint.cpp:194:10:194:10 | x | |
|
||||
| taint.cpp:193:6:193:6 | x | taint.cpp:195:7:195:7 | x | |
|
||||
@@ -5935,6 +5942,7 @@
|
||||
| taint.cpp:194:9:194:10 | ref arg & ... | taint.cpp:194:10:194:10 | x [inner post update] | |
|
||||
| taint.cpp:194:9:194:10 | ref arg & ... | taint.cpp:195:7:195:7 | x | |
|
||||
| taint.cpp:194:10:194:10 | x | taint.cpp:194:9:194:10 | & ... | |
|
||||
| taint.cpp:194:13:194:18 | ref arg source | taint.cpp:192:23:192:28 | source | |
|
||||
| taint.cpp:194:13:194:18 | source | taint.cpp:194:2:194:7 | call to memcpy | TAINT |
|
||||
| taint.cpp:194:13:194:18 | source | taint.cpp:194:9:194:10 | ref arg & ... | TAINT |
|
||||
| taint.cpp:207:6:207:11 | call to source | taint.cpp:207:2:207:13 | ... = ... | |
|
||||
@@ -6040,18 +6048,22 @@
|
||||
| taint.cpp:304:2:304:6 | ... = ... | taint.cpp:304:2:304:2 | a [post update] | |
|
||||
| taint.cpp:304:6:304:6 | b | taint.cpp:302:21:302:21 | a | |
|
||||
| taint.cpp:304:6:304:6 | b | taint.cpp:304:2:304:6 | ... = ... | |
|
||||
| taint.cpp:307:21:307:21 | a | taint.cpp:307:21:307:21 | a | |
|
||||
| taint.cpp:307:21:307:21 | a | taint.cpp:309:3:309:3 | a | |
|
||||
| taint.cpp:307:28:307:28 | b | taint.cpp:309:7:309:7 | b | |
|
||||
| taint.cpp:309:2:309:3 | * ... [post update] | taint.cpp:307:21:307:21 | a | |
|
||||
| taint.cpp:309:2:309:3 | * ... [post update] | taint.cpp:309:3:309:3 | a [inner post update] | |
|
||||
| taint.cpp:309:2:309:7 | ... = ... | taint.cpp:309:2:309:3 | * ... [post update] | |
|
||||
| taint.cpp:309:3:309:3 | a | taint.cpp:309:2:309:3 | * ... | TAINT |
|
||||
| taint.cpp:309:7:309:7 | b | taint.cpp:309:2:309:7 | ... = ... | |
|
||||
| taint.cpp:312:21:312:21 | a | taint.cpp:312:21:312:21 | a | |
|
||||
| taint.cpp:312:21:312:21 | a | taint.cpp:317:3:317:3 | a | |
|
||||
| taint.cpp:312:28:312:28 | b | taint.cpp:316:6:316:6 | b | |
|
||||
| taint.cpp:316:6:316:6 | b | taint.cpp:316:6:316:10 | ... + ... | TAINT |
|
||||
| taint.cpp:316:6:316:10 | ... + ... | taint.cpp:316:2:316:10 | ... = ... | |
|
||||
| taint.cpp:316:6:316:10 | ... + ... | taint.cpp:317:7:317:7 | c | |
|
||||
| taint.cpp:316:10:316:10 | 1 | taint.cpp:316:6:316:10 | ... + ... | TAINT |
|
||||
| taint.cpp:317:2:317:3 | * ... [post update] | taint.cpp:312:21:312:21 | a | |
|
||||
| taint.cpp:317:2:317:3 | * ... [post update] | taint.cpp:317:3:317:3 | a [inner post update] | |
|
||||
| taint.cpp:317:2:317:7 | ... = ... | taint.cpp:317:2:317:3 | * ... [post update] | |
|
||||
| taint.cpp:317:3:317:3 | a | taint.cpp:317:2:317:3 | * ... | TAINT |
|
||||
@@ -6113,6 +6125,7 @@
|
||||
| taint.cpp:347:13:347:13 | d | taint.cpp:347:12:347:13 | & ... | |
|
||||
| taint.cpp:348:14:348:14 | ref arg e | taint.cpp:355:7:355:7 | e | |
|
||||
| taint.cpp:348:17:348:17 | ref arg t | taint.cpp:350:7:350:7 | t | |
|
||||
| taint.cpp:367:24:367:29 | source | taint.cpp:367:24:367:29 | source | |
|
||||
| taint.cpp:367:24:367:29 | source | taint.cpp:371:13:371:18 | source | |
|
||||
| taint.cpp:367:24:367:29 | source | taint.cpp:373:14:373:19 | source | |
|
||||
| taint.cpp:371:6:371:11 | call to strdup | taint.cpp:371:2:371:19 | ... = ... | |
|
||||
@@ -6130,6 +6143,7 @@
|
||||
| taint.cpp:383:6:383:12 | call to strndup | taint.cpp:384:7:384:7 | a | |
|
||||
| taint.cpp:383:14:383:27 | hello, world | taint.cpp:383:6:383:12 | call to strndup | TAINT |
|
||||
| taint.cpp:383:30:383:35 | source | taint.cpp:383:6:383:12 | call to strndup | TAINT |
|
||||
| taint.cpp:387:27:387:32 | source | taint.cpp:387:27:387:32 | source | |
|
||||
| taint.cpp:387:27:387:32 | source | taint.cpp:391:13:391:18 | source | |
|
||||
| taint.cpp:391:6:391:11 | call to wcsdup | taint.cpp:391:2:391:19 | ... = ... | |
|
||||
| taint.cpp:391:6:391:11 | call to wcsdup | taint.cpp:393:7:393:7 | a | |
|
||||
@@ -6137,6 +6151,7 @@
|
||||
| taint.cpp:392:6:392:11 | call to wcsdup | taint.cpp:392:2:392:28 | ... = ... | |
|
||||
| taint.cpp:392:6:392:11 | call to wcsdup | taint.cpp:394:7:394:7 | b | |
|
||||
| taint.cpp:392:13:392:27 | hello, world | taint.cpp:392:6:392:11 | call to wcsdup | TAINT |
|
||||
| taint.cpp:397:25:397:30 | source | taint.cpp:397:25:397:30 | source | |
|
||||
| taint.cpp:397:25:397:30 | source | taint.cpp:401:14:401:19 | source | |
|
||||
| taint.cpp:397:25:397:30 | source | taint.cpp:403:15:403:20 | source | |
|
||||
| taint.cpp:401:6:401:12 | call to strdupa | taint.cpp:401:2:401:20 | ... = ... | |
|
||||
@@ -6239,6 +6254,7 @@
|
||||
| taint.cpp:485:6:485:6 | 0 | taint.cpp:493:7:493:7 | y | |
|
||||
| taint.cpp:490:7:490:7 | ref arg x | taint.cpp:492:7:492:7 | x | |
|
||||
| taint.cpp:490:10:490:10 | ref arg y | taint.cpp:493:7:493:7 | y | |
|
||||
| taint.cpp:502:26:502:32 | source1 | taint.cpp:502:26:502:32 | source1 | |
|
||||
| taint.cpp:502:26:502:32 | source1 | taint.cpp:505:28:505:34 | source1 | |
|
||||
| taint.cpp:503:15:503:21 | 0 | taint.cpp:505:12:505:15 | line | |
|
||||
| taint.cpp:503:15:503:21 | 0 | taint.cpp:507:7:507:10 | line | |
|
||||
@@ -6248,29 +6264,39 @@
|
||||
| taint.cpp:505:12:505:15 | line | taint.cpp:505:11:505:15 | & ... | |
|
||||
| taint.cpp:505:18:505:19 | ref arg & ... | taint.cpp:505:19:505:19 | n [inner post update] | |
|
||||
| taint.cpp:505:19:505:19 | n | taint.cpp:505:18:505:19 | & ... | |
|
||||
| taint.cpp:505:28:505:34 | ref arg source1 | taint.cpp:502:26:502:32 | source1 | |
|
||||
| taint.cpp:505:28:505:34 | source1 | taint.cpp:505:11:505:15 | ref arg & ... | TAINT |
|
||||
| taint.cpp:514:24:514:29 | source | taint.cpp:514:24:514:29 | source | |
|
||||
| taint.cpp:514:24:514:29 | source | taint.cpp:516:27:516:32 | source | |
|
||||
| taint.cpp:515:22:515:29 | ,.-;:_ | taint.cpp:516:35:516:39 | delim | |
|
||||
| taint.cpp:515:22:515:29 | ,.-;:_ | taint.cpp:518:7:518:11 | delim | |
|
||||
| taint.cpp:516:20:516:25 | call to strtok | taint.cpp:517:7:517:15 | tokenized | |
|
||||
| taint.cpp:516:27:516:32 | ref arg source | taint.cpp:514:24:514:29 | source | |
|
||||
| taint.cpp:516:27:516:32 | source | taint.cpp:516:20:516:25 | call to strtok | TAINT |
|
||||
| taint.cpp:525:26:525:28 | ptr | taint.cpp:525:26:525:28 | ptr | |
|
||||
| taint.cpp:525:26:525:28 | ptr | taint.cpp:526:10:526:12 | ptr | |
|
||||
| taint.cpp:525:26:525:28 | ptr | taint.cpp:527:7:527:9 | ptr | |
|
||||
| taint.cpp:525:26:525:28 | ptr | taint.cpp:528:8:528:10 | ptr | |
|
||||
| taint.cpp:525:36:525:41 | source | taint.cpp:526:15:526:20 | source | |
|
||||
| taint.cpp:526:10:526:12 | ptr | taint.cpp:526:2:526:8 | call to _strset | |
|
||||
| taint.cpp:526:10:526:12 | ref arg ptr | taint.cpp:525:26:525:28 | ptr | |
|
||||
| taint.cpp:526:10:526:12 | ref arg ptr | taint.cpp:527:7:527:9 | ptr | |
|
||||
| taint.cpp:526:10:526:12 | ref arg ptr | taint.cpp:528:8:528:10 | ptr | |
|
||||
| taint.cpp:526:15:526:20 | source | taint.cpp:526:2:526:8 | call to _strset | TAINT |
|
||||
| taint.cpp:526:15:526:20 | source | taint.cpp:526:10:526:12 | ref arg ptr | |
|
||||
| taint.cpp:527:7:527:9 | ref arg ptr | taint.cpp:525:26:525:28 | ptr | |
|
||||
| taint.cpp:527:7:527:9 | ref arg ptr | taint.cpp:528:8:528:10 | ptr | |
|
||||
| taint.cpp:528:8:528:10 | ptr | taint.cpp:528:7:528:10 | * ... | TAINT |
|
||||
| taint.cpp:531:26:531:31 | source | taint.cpp:531:26:531:31 | source | |
|
||||
| taint.cpp:531:26:531:31 | source | taint.cpp:532:10:532:15 | source | |
|
||||
| taint.cpp:531:26:531:31 | source | taint.cpp:533:7:533:12 | source | |
|
||||
| taint.cpp:532:10:532:15 | ref arg source | taint.cpp:531:26:531:31 | source | |
|
||||
| taint.cpp:532:10:532:15 | ref arg source | taint.cpp:533:7:533:12 | source | |
|
||||
| taint.cpp:532:10:532:15 | source | taint.cpp:532:2:532:8 | call to _strset | |
|
||||
| taint.cpp:532:18:532:18 | 0 | taint.cpp:532:2:532:8 | call to _strset | TAINT |
|
||||
| taint.cpp:532:18:532:18 | 0 | taint.cpp:532:10:532:15 | ref arg source | |
|
||||
| taint.cpp:533:7:533:12 | ref arg source | taint.cpp:531:26:531:31 | source | |
|
||||
| taint.cpp:540:24:540:29 | source | taint.cpp:540:24:540:29 | source | |
|
||||
| taint.cpp:540:24:540:29 | source | taint.cpp:542:14:542:19 | source | |
|
||||
| taint.cpp:541:6:541:6 | x | taint.cpp:542:11:542:11 | x | |
|
||||
| taint.cpp:541:6:541:6 | x | taint.cpp:543:7:543:7 | x | |
|
||||
@@ -6280,6 +6306,7 @@
|
||||
| taint.cpp:542:11:542:11 | x | taint.cpp:542:10:542:11 | & ... | |
|
||||
| taint.cpp:542:14:542:19 | source | taint.cpp:542:2:542:8 | call to mempcpy | TAINT |
|
||||
| taint.cpp:542:14:542:19 | source | taint.cpp:542:10:542:11 | ref arg & ... | TAINT |
|
||||
| taint.cpp:550:24:550:29 | source | taint.cpp:550:24:550:29 | source | |
|
||||
| taint.cpp:550:24:550:29 | source | taint.cpp:552:16:552:21 | source | |
|
||||
| taint.cpp:551:6:551:9 | dest | taint.cpp:552:10:552:13 | dest | |
|
||||
| taint.cpp:551:6:551:9 | dest | taint.cpp:552:35:552:38 | dest | |
|
||||
@@ -6288,29 +6315,42 @@
|
||||
| taint.cpp:552:10:552:13 | ref arg dest | taint.cpp:553:7:553:10 | dest | |
|
||||
| taint.cpp:552:16:552:21 | source | taint.cpp:552:2:552:8 | call to memccpy | TAINT |
|
||||
| taint.cpp:552:16:552:21 | source | taint.cpp:552:10:552:13 | ref arg dest | TAINT |
|
||||
| taint.cpp:560:24:560:28 | dest1 | taint.cpp:560:24:560:28 | dest1 | |
|
||||
| taint.cpp:560:24:560:28 | dest1 | taint.cpp:561:9:561:13 | dest1 | |
|
||||
| taint.cpp:560:24:560:28 | dest1 | taint.cpp:562:7:562:11 | dest1 | |
|
||||
| taint.cpp:560:37:560:41 | dest2 | taint.cpp:560:37:560:41 | dest2 | |
|
||||
| taint.cpp:560:37:560:41 | dest2 | taint.cpp:564:9:564:13 | dest2 | |
|
||||
| taint.cpp:560:37:560:41 | dest2 | taint.cpp:565:7:565:11 | dest2 | |
|
||||
| taint.cpp:560:50:560:54 | clean | taint.cpp:560:50:560:54 | clean | |
|
||||
| taint.cpp:560:50:560:54 | clean | taint.cpp:564:16:564:20 | clean | |
|
||||
| taint.cpp:560:63:560:68 | source | taint.cpp:560:63:560:68 | source | |
|
||||
| taint.cpp:560:63:560:68 | source | taint.cpp:561:16:561:21 | source | |
|
||||
| taint.cpp:561:9:561:13 | dest1 | taint.cpp:561:2:561:7 | call to strcat | |
|
||||
| taint.cpp:561:9:561:13 | dest1 | taint.cpp:561:9:561:13 | ref arg dest1 | TAINT |
|
||||
| taint.cpp:561:9:561:13 | ref arg dest1 | taint.cpp:560:24:560:28 | dest1 | |
|
||||
| taint.cpp:561:9:561:13 | ref arg dest1 | taint.cpp:562:7:562:11 | dest1 | |
|
||||
| taint.cpp:561:16:561:21 | source | taint.cpp:561:9:561:13 | ref arg dest1 | TAINT |
|
||||
| taint.cpp:562:7:562:11 | ref arg dest1 | taint.cpp:560:24:560:28 | dest1 | |
|
||||
| taint.cpp:564:9:564:13 | dest2 | taint.cpp:564:2:564:7 | call to strcat | |
|
||||
| taint.cpp:564:9:564:13 | dest2 | taint.cpp:564:9:564:13 | ref arg dest2 | TAINT |
|
||||
| taint.cpp:564:9:564:13 | ref arg dest2 | taint.cpp:560:37:560:41 | dest2 | |
|
||||
| taint.cpp:564:9:564:13 | ref arg dest2 | taint.cpp:565:7:565:11 | dest2 | |
|
||||
| taint.cpp:564:16:564:20 | clean | taint.cpp:564:9:564:13 | ref arg dest2 | TAINT |
|
||||
| taint.cpp:565:7:565:11 | ref arg dest2 | taint.cpp:560:37:560:41 | dest2 | |
|
||||
| taint.cpp:572:37:572:41 | dest1 | taint.cpp:572:37:572:41 | dest1 | |
|
||||
| taint.cpp:572:37:572:41 | dest1 | taint.cpp:574:36:574:40 | dest1 | |
|
||||
| taint.cpp:572:37:572:41 | dest1 | taint.cpp:575:7:575:11 | dest1 | |
|
||||
| taint.cpp:572:37:572:41 | dest1 | taint.cpp:576:8:576:12 | dest1 | |
|
||||
| taint.cpp:572:65:572:67 | ptr | taint.cpp:572:65:572:67 | ptr | |
|
||||
| taint.cpp:572:65:572:67 | ptr | taint.cpp:574:43:574:45 | ptr | |
|
||||
| taint.cpp:572:65:572:67 | ptr | taint.cpp:580:43:580:45 | ptr | |
|
||||
| taint.cpp:572:85:572:89 | dest3 | taint.cpp:572:85:572:89 | dest3 | |
|
||||
| taint.cpp:572:85:572:89 | dest3 | taint.cpp:580:36:580:40 | dest3 | |
|
||||
| taint.cpp:572:85:572:89 | dest3 | taint.cpp:581:7:581:11 | dest3 | |
|
||||
| taint.cpp:572:85:572:89 | dest3 | taint.cpp:582:8:582:12 | dest3 | |
|
||||
| taint.cpp:573:32:573:36 | clean | taint.cpp:573:32:573:36 | clean | |
|
||||
| taint.cpp:573:32:573:36 | clean | taint.cpp:580:51:580:55 | clean | |
|
||||
| taint.cpp:573:49:573:54 | source | taint.cpp:573:49:573:54 | source | |
|
||||
| taint.cpp:573:49:573:54 | source | taint.cpp:574:51:574:56 | source | |
|
||||
| taint.cpp:573:61:573:61 | n | taint.cpp:574:48:574:48 | n | |
|
||||
| taint.cpp:573:61:573:61 | n | taint.cpp:580:48:580:48 | n | |
|
||||
@@ -6318,11 +6358,14 @@
|
||||
| taint.cpp:574:25:574:34 | call to _mbsncat_l | taint.cpp:578:8:578:12 | dest2 | |
|
||||
| taint.cpp:574:36:574:40 | dest1 | taint.cpp:574:25:574:34 | call to _mbsncat_l | |
|
||||
| taint.cpp:574:36:574:40 | dest1 | taint.cpp:574:36:574:40 | ref arg dest1 | TAINT |
|
||||
| taint.cpp:574:36:574:40 | ref arg dest1 | taint.cpp:572:37:572:41 | dest1 | |
|
||||
| taint.cpp:574:36:574:40 | ref arg dest1 | taint.cpp:575:7:575:11 | dest1 | |
|
||||
| taint.cpp:574:36:574:40 | ref arg dest1 | taint.cpp:576:8:576:12 | dest1 | |
|
||||
| taint.cpp:574:43:574:45 | ptr | taint.cpp:574:36:574:40 | ref arg dest1 | TAINT |
|
||||
| taint.cpp:574:48:574:48 | n | taint.cpp:574:36:574:40 | ref arg dest1 | TAINT |
|
||||
| taint.cpp:574:51:574:56 | ref arg source | taint.cpp:573:49:573:54 | source | |
|
||||
| taint.cpp:574:51:574:56 | source | taint.cpp:574:36:574:40 | ref arg dest1 | TAINT |
|
||||
| taint.cpp:575:7:575:11 | ref arg dest1 | taint.cpp:572:37:572:41 | dest1 | |
|
||||
| taint.cpp:575:7:575:11 | ref arg dest1 | taint.cpp:576:8:576:12 | dest1 | |
|
||||
| taint.cpp:576:8:576:12 | dest1 | taint.cpp:576:7:576:12 | * ... | TAINT |
|
||||
| taint.cpp:577:7:577:11 | ref arg dest2 | taint.cpp:578:8:578:12 | dest2 | |
|
||||
@@ -6331,15 +6374,19 @@
|
||||
| taint.cpp:580:25:580:34 | call to _mbsncat_l | taint.cpp:584:8:584:12 | dest4 | |
|
||||
| taint.cpp:580:36:580:40 | dest3 | taint.cpp:580:25:580:34 | call to _mbsncat_l | |
|
||||
| taint.cpp:580:36:580:40 | dest3 | taint.cpp:580:36:580:40 | ref arg dest3 | TAINT |
|
||||
| taint.cpp:580:36:580:40 | ref arg dest3 | taint.cpp:572:85:572:89 | dest3 | |
|
||||
| taint.cpp:580:36:580:40 | ref arg dest3 | taint.cpp:581:7:581:11 | dest3 | |
|
||||
| taint.cpp:580:36:580:40 | ref arg dest3 | taint.cpp:582:8:582:12 | dest3 | |
|
||||
| taint.cpp:580:43:580:45 | ptr | taint.cpp:580:36:580:40 | ref arg dest3 | TAINT |
|
||||
| taint.cpp:580:48:580:48 | n | taint.cpp:580:36:580:40 | ref arg dest3 | TAINT |
|
||||
| taint.cpp:580:51:580:55 | clean | taint.cpp:580:36:580:40 | ref arg dest3 | TAINT |
|
||||
| taint.cpp:580:51:580:55 | ref arg clean | taint.cpp:573:32:573:36 | clean | |
|
||||
| taint.cpp:581:7:581:11 | ref arg dest3 | taint.cpp:572:85:572:89 | dest3 | |
|
||||
| taint.cpp:581:7:581:11 | ref arg dest3 | taint.cpp:582:8:582:12 | dest3 | |
|
||||
| taint.cpp:582:8:582:12 | dest3 | taint.cpp:582:7:582:12 | * ... | TAINT |
|
||||
| taint.cpp:583:7:583:11 | ref arg dest4 | taint.cpp:584:8:584:12 | dest4 | |
|
||||
| taint.cpp:584:8:584:12 | dest4 | taint.cpp:584:7:584:12 | * ... | TAINT |
|
||||
| taint.cpp:591:24:591:29 | source | taint.cpp:591:24:591:29 | source | |
|
||||
| taint.cpp:591:24:591:29 | source | taint.cpp:594:29:594:34 | source | |
|
||||
| taint.cpp:592:23:592:30 | ,.-;:_ | taint.cpp:594:37:594:41 | delim | |
|
||||
| taint.cpp:594:9:594:17 | tokenized | taint.cpp:594:9:594:42 | ... = ... | |
|
||||
@@ -6347,6 +6394,7 @@
|
||||
| taint.cpp:594:21:594:26 | call to strsep | taint.cpp:595:10:595:18 | tokenized | |
|
||||
| taint.cpp:594:21:594:26 | call to strsep | taint.cpp:596:11:596:19 | tokenized | |
|
||||
| taint.cpp:594:28:594:34 | & ... | taint.cpp:594:21:594:26 | call to strsep | TAINT |
|
||||
| taint.cpp:594:28:594:34 | ref arg & ... | taint.cpp:591:24:591:29 | source | |
|
||||
| taint.cpp:594:28:594:34 | ref arg & ... | taint.cpp:594:29:594:34 | source | |
|
||||
| taint.cpp:594:28:594:34 | ref arg & ... | taint.cpp:594:29:594:34 | source [inner post update] | |
|
||||
| taint.cpp:594:29:594:34 | source | taint.cpp:594:21:594:26 | call to strsep | TAINT |
|
||||
@@ -6354,45 +6402,63 @@
|
||||
| taint.cpp:594:37:594:41 | delim | taint.cpp:594:21:594:26 | call to strsep | TAINT |
|
||||
| taint.cpp:595:10:595:18 | ref arg tokenized | taint.cpp:596:11:596:19 | tokenized | |
|
||||
| taint.cpp:596:11:596:19 | tokenized | taint.cpp:596:10:596:19 | * ... | TAINT |
|
||||
| taint.cpp:606:25:606:30 | source | taint.cpp:606:25:606:30 | source | |
|
||||
| taint.cpp:606:25:606:30 | source | taint.cpp:607:18:607:23 | source | |
|
||||
| taint.cpp:606:39:606:43 | clean | taint.cpp:606:39:606:43 | clean | |
|
||||
| taint.cpp:606:39:606:43 | clean | taint.cpp:611:18:611:22 | clean | |
|
||||
| taint.cpp:606:82:606:87 | locale | taint.cpp:606:82:606:87 | locale | |
|
||||
| taint.cpp:606:82:606:87 | locale | taint.cpp:607:26:607:31 | locale | |
|
||||
| taint.cpp:606:82:606:87 | locale | taint.cpp:611:25:611:30 | locale | |
|
||||
| taint.cpp:607:10:607:16 | call to _strinc | taint.cpp:606:52:606:56 | dest1 | |
|
||||
| taint.cpp:607:10:607:16 | call to _strinc | taint.cpp:607:2:607:32 | ... = ... | |
|
||||
| taint.cpp:607:10:607:16 | call to _strinc | taint.cpp:608:7:608:11 | dest1 | |
|
||||
| taint.cpp:607:10:607:16 | call to _strinc | taint.cpp:609:8:609:12 | dest1 | |
|
||||
| taint.cpp:607:18:607:23 | source | taint.cpp:607:10:607:16 | call to _strinc | TAINT |
|
||||
| taint.cpp:607:26:607:31 | locale | taint.cpp:607:10:607:16 | call to _strinc | TAINT |
|
||||
| taint.cpp:607:26:607:31 | ref arg locale | taint.cpp:606:82:606:87 | locale | |
|
||||
| taint.cpp:607:26:607:31 | ref arg locale | taint.cpp:611:25:611:30 | locale | |
|
||||
| taint.cpp:608:7:608:11 | ref arg dest1 | taint.cpp:606:52:606:56 | dest1 | |
|
||||
| taint.cpp:608:7:608:11 | ref arg dest1 | taint.cpp:609:8:609:12 | dest1 | |
|
||||
| taint.cpp:609:8:609:12 | dest1 | taint.cpp:609:7:609:12 | * ... | TAINT |
|
||||
| taint.cpp:611:10:611:16 | call to _strinc | taint.cpp:606:65:606:69 | dest2 | |
|
||||
| taint.cpp:611:10:611:16 | call to _strinc | taint.cpp:611:2:611:31 | ... = ... | |
|
||||
| taint.cpp:611:10:611:16 | call to _strinc | taint.cpp:612:7:612:11 | dest2 | |
|
||||
| taint.cpp:611:10:611:16 | call to _strinc | taint.cpp:613:8:613:12 | dest2 | |
|
||||
| taint.cpp:611:18:611:22 | clean | taint.cpp:611:10:611:16 | call to _strinc | TAINT |
|
||||
| taint.cpp:611:25:611:30 | locale | taint.cpp:611:10:611:16 | call to _strinc | TAINT |
|
||||
| taint.cpp:611:25:611:30 | ref arg locale | taint.cpp:606:82:606:87 | locale | |
|
||||
| taint.cpp:612:7:612:11 | ref arg dest2 | taint.cpp:606:65:606:69 | dest2 | |
|
||||
| taint.cpp:612:7:612:11 | ref arg dest2 | taint.cpp:613:8:613:12 | dest2 | |
|
||||
| taint.cpp:613:8:613:12 | dest2 | taint.cpp:613:7:613:12 | * ... | TAINT |
|
||||
| taint.cpp:616:34:616:48 | source_unsigned | taint.cpp:616:34:616:48 | source_unsigned | |
|
||||
| taint.cpp:616:34:616:48 | source_unsigned | taint.cpp:617:26:617:40 | source_unsigned | |
|
||||
| taint.cpp:616:57:616:62 | source | taint.cpp:616:57:616:62 | source | |
|
||||
| taint.cpp:616:57:616:62 | source | taint.cpp:621:40:621:45 | source | |
|
||||
| taint.cpp:617:18:617:24 | call to _mbsinc | taint.cpp:616:80:616:92 | dest_unsigned | |
|
||||
| taint.cpp:617:18:617:24 | call to _mbsinc | taint.cpp:617:2:617:41 | ... = ... | |
|
||||
| taint.cpp:617:18:617:24 | call to _mbsinc | taint.cpp:618:7:618:19 | dest_unsigned | |
|
||||
| taint.cpp:617:18:617:24 | call to _mbsinc | taint.cpp:619:8:619:20 | dest_unsigned | |
|
||||
| taint.cpp:617:26:617:40 | source_unsigned | taint.cpp:617:18:617:24 | call to _mbsinc | TAINT |
|
||||
| taint.cpp:618:7:618:19 | ref arg dest_unsigned | taint.cpp:616:80:616:92 | dest_unsigned | |
|
||||
| taint.cpp:618:7:618:19 | ref arg dest_unsigned | taint.cpp:619:8:619:20 | dest_unsigned | |
|
||||
| taint.cpp:619:8:619:20 | dest_unsigned | taint.cpp:619:7:619:20 | * ... | TAINT |
|
||||
| taint.cpp:621:16:621:22 | call to _mbsinc | taint.cpp:616:101:616:104 | dest | |
|
||||
| taint.cpp:621:16:621:22 | call to _mbsinc | taint.cpp:621:2:621:46 | ... = ... | |
|
||||
| taint.cpp:621:16:621:22 | call to _mbsinc | taint.cpp:622:7:622:10 | dest | |
|
||||
| taint.cpp:621:16:621:22 | call to _mbsinc | taint.cpp:623:8:623:11 | dest | |
|
||||
| taint.cpp:621:40:621:45 | source | taint.cpp:621:16:621:22 | call to _mbsinc | TAINT |
|
||||
| taint.cpp:622:7:622:10 | ref arg dest | taint.cpp:616:101:616:104 | dest | |
|
||||
| taint.cpp:622:7:622:10 | ref arg dest | taint.cpp:623:8:623:11 | dest | |
|
||||
| taint.cpp:623:8:623:11 | dest | taint.cpp:623:7:623:11 | * ... | TAINT |
|
||||
| taint.cpp:626:40:626:45 | source | taint.cpp:626:40:626:45 | source | |
|
||||
| taint.cpp:626:40:626:45 | source | taint.cpp:627:18:627:23 | source | |
|
||||
| taint.cpp:626:40:626:45 | source | taint.cpp:627:31:627:36 | source | |
|
||||
| taint.cpp:626:40:626:45 | source | taint.cpp:633:25:633:30 | source | |
|
||||
| taint.cpp:626:40:626:45 | source | taint.cpp:638:18:638:23 | source | |
|
||||
| taint.cpp:626:63:626:67 | clean | taint.cpp:626:63:626:67 | clean | |
|
||||
| taint.cpp:626:63:626:67 | clean | taint.cpp:633:18:633:22 | clean | |
|
||||
| taint.cpp:626:63:626:67 | clean | taint.cpp:638:26:638:30 | clean | |
|
||||
| taint.cpp:627:10:627:16 | call to _strdec | taint.cpp:626:85:626:89 | dest1 | |
|
||||
| taint.cpp:627:10:627:16 | call to _strdec | taint.cpp:627:2:627:37 | ... = ... | |
|
||||
| taint.cpp:627:10:627:16 | call to _strdec | taint.cpp:628:7:628:11 | dest1 | |
|
||||
| taint.cpp:627:10:627:16 | call to _strdec | taint.cpp:629:8:629:12 | dest1 | |
|
||||
@@ -6400,20 +6466,25 @@
|
||||
| taint.cpp:627:18:627:28 | ... + ... | taint.cpp:627:10:627:16 | call to _strdec | TAINT |
|
||||
| taint.cpp:627:27:627:28 | 12 | taint.cpp:627:18:627:28 | ... + ... | TAINT |
|
||||
| taint.cpp:627:31:627:36 | source | taint.cpp:627:10:627:16 | call to _strdec | TAINT |
|
||||
| taint.cpp:628:7:628:11 | ref arg dest1 | taint.cpp:626:85:626:89 | dest1 | |
|
||||
| taint.cpp:628:7:628:11 | ref arg dest1 | taint.cpp:629:8:629:12 | dest1 | |
|
||||
| taint.cpp:629:8:629:12 | dest1 | taint.cpp:629:7:629:12 | * ... | TAINT |
|
||||
| taint.cpp:633:10:633:16 | call to _strdec | taint.cpp:626:107:626:111 | dest2 | |
|
||||
| taint.cpp:633:10:633:16 | call to _strdec | taint.cpp:633:2:633:31 | ... = ... | |
|
||||
| taint.cpp:633:10:633:16 | call to _strdec | taint.cpp:634:7:634:11 | dest2 | |
|
||||
| taint.cpp:633:10:633:16 | call to _strdec | taint.cpp:635:8:635:12 | dest2 | |
|
||||
| taint.cpp:633:18:633:22 | clean | taint.cpp:633:10:633:16 | call to _strdec | TAINT |
|
||||
| taint.cpp:633:25:633:30 | source | taint.cpp:633:10:633:16 | call to _strdec | TAINT |
|
||||
| taint.cpp:634:7:634:11 | ref arg dest2 | taint.cpp:626:107:626:111 | dest2 | |
|
||||
| taint.cpp:634:7:634:11 | ref arg dest2 | taint.cpp:635:8:635:12 | dest2 | |
|
||||
| taint.cpp:635:8:635:12 | dest2 | taint.cpp:635:7:635:12 | * ... | TAINT |
|
||||
| taint.cpp:638:10:638:16 | call to _strdec | taint.cpp:626:129:626:133 | dest3 | |
|
||||
| taint.cpp:638:10:638:16 | call to _strdec | taint.cpp:638:2:638:31 | ... = ... | |
|
||||
| taint.cpp:638:10:638:16 | call to _strdec | taint.cpp:639:7:639:11 | dest3 | |
|
||||
| taint.cpp:638:10:638:16 | call to _strdec | taint.cpp:640:8:640:12 | dest3 | |
|
||||
| taint.cpp:638:18:638:23 | source | taint.cpp:638:10:638:16 | call to _strdec | TAINT |
|
||||
| taint.cpp:638:26:638:30 | clean | taint.cpp:638:10:638:16 | call to _strdec | TAINT |
|
||||
| taint.cpp:639:7:639:11 | ref arg dest3 | taint.cpp:626:129:626:133 | dest3 | |
|
||||
| taint.cpp:639:7:639:11 | ref arg dest3 | taint.cpp:640:8:640:12 | dest3 | |
|
||||
| taint.cpp:640:8:640:12 | dest3 | taint.cpp:640:7:640:12 | * ... | TAINT |
|
||||
| taint.cpp:647:33:647:38 | source | taint.cpp:650:17:650:22 | source | |
|
||||
@@ -6427,19 +6498,23 @@
|
||||
| taint.cpp:653:6:653:14 | call to _strnextc | taint.cpp:654:7:654:7 | c | |
|
||||
| taint.cpp:653:16:653:17 | | taint.cpp:653:6:653:14 | call to _strnextc | TAINT |
|
||||
| taint.cpp:662:9:662:12 | this | taint.cpp:662:25:662:29 | this | |
|
||||
| taint.cpp:665:33:665:38 | source | taint.cpp:665:33:665:38 | source | |
|
||||
| taint.cpp:665:33:665:38 | source | taint.cpp:667:20:667:25 | source | |
|
||||
| taint.cpp:666:30:666:30 | c | taint.cpp:667:10:667:10 | c | |
|
||||
| taint.cpp:666:30:666:30 | c | taint.cpp:668:8:668:8 | c | |
|
||||
| taint.cpp:667:10:667:10 | ref arg c | taint.cpp:668:8:668:8 | c | |
|
||||
| taint.cpp:667:12:667:15 | call to data | taint.cpp:667:3:667:8 | call to memcpy | |
|
||||
| taint.cpp:667:20:667:25 | ref arg source | taint.cpp:665:33:665:38 | source | |
|
||||
| taint.cpp:667:20:667:25 | source | taint.cpp:667:3:667:8 | call to memcpy | TAINT |
|
||||
| taint.cpp:667:20:667:25 | source | taint.cpp:667:12:667:15 | ref arg call to data | TAINT |
|
||||
| taint.cpp:674:9:674:12 | this | taint.cpp:674:31:674:35 | this | |
|
||||
| taint.cpp:677:35:677:40 | source | taint.cpp:677:35:677:40 | source | |
|
||||
| taint.cpp:677:35:677:40 | source | taint.cpp:679:20:679:25 | source | |
|
||||
| taint.cpp:678:27:678:27 | c | taint.cpp:679:10:679:10 | c | |
|
||||
| taint.cpp:678:27:678:27 | c | taint.cpp:680:8:680:8 | c | |
|
||||
| taint.cpp:679:10:679:10 | ref arg c | taint.cpp:680:8:680:8 | c | |
|
||||
| taint.cpp:679:12:679:15 | call to data | taint.cpp:679:3:679:8 | call to memcpy | |
|
||||
| taint.cpp:679:20:679:25 | ref arg source | taint.cpp:677:35:677:40 | source | |
|
||||
| taint.cpp:679:20:679:25 | source | taint.cpp:679:3:679:8 | call to memcpy | TAINT |
|
||||
| taint.cpp:679:20:679:25 | source | taint.cpp:679:12:679:15 | ref arg call to data | TAINT |
|
||||
| taint.cpp:690:14:690:14 | s | taint.cpp:691:18:691:18 | s | |
|
||||
@@ -7782,6 +7857,7 @@
|
||||
| vector.cpp:413:11:413:16 | call to source | vector.cpp:413:2:413:2 | call to operator* [post update] | TAINT |
|
||||
| vector.cpp:413:11:413:16 | call to source | vector.cpp:413:2:413:18 | ... = ... | |
|
||||
| vector.cpp:414:7:414:9 | ref arg v14 | vector.cpp:415:1:415:1 | v14 | |
|
||||
| vector.cpp:417:33:417:45 | source_string | vector.cpp:417:33:417:45 | source_string | |
|
||||
| vector.cpp:417:33:417:45 | source_string | vector.cpp:421:23:421:35 | source_string | |
|
||||
| vector.cpp:417:33:417:45 | source_string | vector.cpp:428:23:428:35 | source_string | |
|
||||
| vector.cpp:417:33:417:45 | source_string | vector.cpp:442:23:442:35 | source_string | |
|
||||
|
||||
@@ -126,15 +126,15 @@ void pointer_test() {
|
||||
|
||||
*p2 = source();
|
||||
|
||||
sink(*p1); // $ ast MISSING: ir
|
||||
sink(*p1); // $ ast,ir
|
||||
sink(*p2); // $ ast,ir
|
||||
sink(*p3);
|
||||
|
||||
p3 = &t1;
|
||||
sink(*p3); // $ ast MISSING: ir
|
||||
sink(*p3); // $ ast,ir
|
||||
|
||||
*p3 = 0;
|
||||
sink(*p3); // $ SPURIOUS: ast
|
||||
sink(*p3); // $ SPURIOUS: ast,ir
|
||||
}
|
||||
|
||||
// --- return values ---
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
private import cpp
|
||||
|
||||
/**
|
||||
* Holds if the specified location is in standard headers.
|
||||
*/
|
||||
predicate locationIsInStandardHeaders(Location loc) {
|
||||
loc.getFile().getAbsolutePath().regexpMatch(".*/include/[^/]+")
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the AST or IR for the specified function should be printed in the test output.
|
||||
*
|
||||
* This predicate excludes functions defined in standard headers.
|
||||
*/
|
||||
predicate shouldDumpFunction(Function func) {
|
||||
not func.getLocation().getFile().getAbsolutePath().regexpMatch(".*/include/[^/]+")
|
||||
}
|
||||
predicate shouldDumpFunction(Function func) { not locationIsInStandardHeaders(func.getLocation()) }
|
||||
|
||||
6999
cpp/ql/test/library-tests/ir/ir/operand_locations.expected
Normal file
6999
cpp/ql/test/library-tests/ir/ir/operand_locations.expected
Normal file
File diff suppressed because it is too large
Load Diff
7
cpp/ql/test/library-tests/ir/ir/operand_locations.ql
Normal file
7
cpp/ql/test/library-tests/ir/ir/operand_locations.ql
Normal file
@@ -0,0 +1,7 @@
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import PrintConfig
|
||||
|
||||
from Operand a
|
||||
where not locationIsInStandardHeaders(a.getLocation())
|
||||
select a, a.getDumpString()
|
||||
@@ -1474,7 +1474,7 @@ reverseRead
|
||||
argHasPostUpdate
|
||||
postWithInFlow
|
||||
| FunctionTryStmt.cpp:2:3:2:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| VacuousDestructorCall.cpp:10:3:10:16 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| VacuousDestructorCall.cpp:10:21:10:22 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| VacuousDestructorCall.cpp:10:21:10:22 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| VacuousDestructorCall.cpp:10:22:10:22 | i [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| abortingfunctions.cpp:49:5:49:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -1497,7 +1497,7 @@ postWithInFlow
|
||||
| bad_asts.cpp:10:7:10:23 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| bad_asts.cpp:15:10:15:12 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| bad_asts.cpp:16:5:16:5 | s [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| bad_asts.cpp:16:7:16:23 | s [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| bad_asts.cpp:16:5:16:5 | s [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| bad_asts.cpp:27:11:27:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| break_labels.c:3:9:3:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| break_labels.c:5:9:5:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -1520,35 +1520,35 @@ postWithInFlow
|
||||
| builtin.c:22:3:22:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:29:5:29:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:34:3:34:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:34:10:34:20 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:34:22:34:31 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:34:22:34:31 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:34:22:34:31 | (volatile void *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:34:23:34:31 | staticint [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:39:3:39:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:39:10:39:23 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:39:36:39:45 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:39:36:39:45 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:39:37:39:45 | carry_out [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:43:3:43:24 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:43:40:43:49 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:43:40:43:49 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:43:41:43:49 | staticint [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:45:3:45:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:48:2:48:4 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:51:3:51:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:51:10:51:27 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:51:29:51:38 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:51:29:51:38 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:51:30:51:38 | staticint [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:54:3:54:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:54:10:54:26 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:54:28:54:38 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:54:28:54:38 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:54:29:54:38 | atomic_int [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.c:56:3:56:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.cpp:5:5:5:34 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.cpp:10:10:10:10 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.cpp:10:14:10:22 | i [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.cpp:10:24:10:24 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.cpp:10:24:10:24 | i [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.cpp:10:24:10:24 | i [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.cpp:14:11:14:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.cpp:15:5:15:29 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.cpp:15:31:15:35 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.cpp:15:31:15:35 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.cpp:15:32:15:35 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| builtin.cpp:15:33:15:35 | ptr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -1559,18 +1559,18 @@ postWithInFlow
|
||||
| condition_decls.cpp:3:13:3:22 | Call [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:3:13:3:22 | new [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:9:5:9:18 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:16:6:16:20 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:16:6:16:20 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:16:19:16:20 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:26:10:26:24 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:26:10:26:24 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:26:23:26:24 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:41:9:41:23 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:41:9:41:23 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:41:22:41:23 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:48:16:48:19 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:48:16:48:19 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:48:22:48:24 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:48:27:48:31 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:48:27:48:31 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:48:34:48:36 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:48:39:48:53 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:48:39:48:53 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| condition_decls.cpp:48:52:48:53 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| conditional_destructors.cpp:6:13:6:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| conditional_destructors.cpp:6:13:6:15 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| conditional_destructors.cpp:10:9:10:32 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -1594,8 +1594,8 @@ postWithInFlow
|
||||
| conditional_destructors.cpp:42:18:42:22 | call to C2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| conditional_destructors.cpp:42:18:42:22 | temporary object [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| constmemberaccess.cpp:9:2:9:2 | i [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| constructorinitializer.cpp:8:4:8:4 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| constructorinitializer.cpp:8:4:8:4 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| constructorinitializer.cpp:8:6:8:18 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:6:5:6:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:6:5:6:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:6:5:6:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -1650,13 +1650,13 @@ postWithInFlow
|
||||
| cpp17.cpp:15:5:15:45 | Call [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp17.cpp:15:5:15:45 | new [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp17.cpp:15:5:15:45 | new [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp17.cpp:19:5:19:8 | 1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp17.cpp:19:5:19:8 | 2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp17.cpp:19:5:19:8 | p [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp17.cpp:19:10:19:10 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp17.cpp:19:10:19:10 | p [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp17.cpp:19:10:19:10 | p [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp17.cpp:19:13:19:13 | 1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp17.cpp:19:13:19:13 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp17.cpp:19:13:19:13 | temporary object [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp17.cpp:19:16:19:16 | 2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp17.cpp:19:16:19:16 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp17.cpp:19:16:19:16 | temporary object [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| defdestructordeleteexpr.cpp:4:5:4:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -1982,20 +1982,20 @@ postWithInFlow
|
||||
| ir.cpp:579:10:579:10 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:579:16:579:21 | PointerAdd [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:579:16:579:21 | PointerAdd [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:585:5:585:18 | string [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:585:32:585:39 | array to pointer conversion [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:585:32:585:39 | string [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:585:32:585:39 | string [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:591:11:591:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:592:5:592:7 | pfn [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:593:5:593:7 | pfn [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:594:5:594:7 | pfn [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:616:12:616:13 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:616:12:616:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:617:12:617:13 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:617:12:617:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:617:15:617:22 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:618:12:618:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:619:12:619:13 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:619:12:619:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:619:16:619:30 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:631:9:631:17 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:635:9:635:17 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:639:9:639:17 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -2011,11 +2011,11 @@ postWithInFlow
|
||||
| ir.cpp:649:9:649:9 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:653:9:653:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:653:9:653:12 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:653:15:653:36 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:653:9:653:12 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:654:10:654:14 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:654:10:654:14 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:654:11:654:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:654:11:654:14 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:654:17:654:38 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:655:9:655:30 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:655:9:655:30 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:655:9:655:30 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -2042,7 +2042,7 @@ postWithInFlow
|
||||
| ir.cpp:716:5:716:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:716:12:716:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:721:3:721:54 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:721:10:721:39 | 0 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:721:41:721:47 | 0 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:721:41:721:47 | (void *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:726:9:726:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:728:7:728:28 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -2110,13 +2110,13 @@ postWithInFlow
|
||||
| ir.cpp:805:11:805:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:806:12:806:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:808:3:808:3 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:808:5:808:5 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:808:3:808:3 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:809:3:809:3 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:809:3:809:3 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:809:5:809:5 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:809:7:809:13 | call to Base [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:809:7:809:13 | temporary object [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:810:3:810:3 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:810:5:810:5 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:810:3:810:3 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:810:7:810:26 | call to Base [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:810:7:810:26 | temporary object [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:811:3:811:4 | pb [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -2124,20 +2124,20 @@ postWithInFlow
|
||||
| ir.cpp:813:3:813:4 | pb [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:814:3:814:4 | pb [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:816:3:816:3 | m [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:816:5:816:5 | m [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:816:3:816:3 | m [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:817:3:817:3 | m [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:817:3:817:3 | m [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:817:5:817:5 | m [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:818:3:818:4 | pm [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:819:3:819:4 | pm [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:820:3:820:4 | pm [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:822:3:822:3 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:822:5:822:5 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:822:3:822:3 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:823:3:823:3 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:823:3:823:3 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:823:5:823:5 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:823:7:823:13 | call to Base [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:823:7:823:13 | temporary object [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:824:3:824:3 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:824:5:824:5 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:824:3:824:3 | b [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:824:7:824:26 | call to Base [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:824:7:824:26 | temporary object [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:825:3:825:4 | pb [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -2145,9 +2145,9 @@ postWithInFlow
|
||||
| ir.cpp:827:3:827:4 | pb [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:828:3:828:4 | pb [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:830:3:830:3 | d [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:830:5:830:5 | d [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:830:3:830:3 | d [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:831:3:831:3 | d [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:831:3:831:3 | d [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:831:5:831:5 | d [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:832:3:832:4 | pd [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:833:3:833:4 | pd [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:834:3:834:4 | pd [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -2170,8 +2170,8 @@ postWithInFlow
|
||||
| ir.cpp:861:23:861:24 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:863:9:863:10 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:864:15:864:17 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:867:1:867:14 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:867:1:867:14 | this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:868:3:868:12 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:873:15:873:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:874:3:874:3 | p [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ir.cpp:875:3:875:3 | p [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -2293,23 +2293,23 @@ postWithInFlow
|
||||
| misc.c:229:7:229:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:230:2:230:3 | p1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:231:2:231:40 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| modeled-functions.cpp:6:3:6:8 | 0 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| modeled-functions.cpp:6:3:6:8 | 0 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| modeled-functions.cpp:6:19:6:19 | 0 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| modeled-functions.cpp:6:19:6:19 | (char *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| modeled-functions.cpp:6:22:6:22 | 0 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| modeled-functions.cpp:6:22:6:22 | (unsigned long *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_assume.cpp:13:8:13:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_assume.cpp:14:8:14:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_assume.cpp:28:3:28:8 | result [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_assume.cpp:28:12:28:16 | buffer [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_assume.cpp:28:18:28:23 | array to pointer conversion [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_assume.cpp:28:18:28:23 | buffer [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_assume.cpp:28:18:28:23 | buffer [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_assume.cpp:34:1:34:1 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_try_mix.cpp:11:7:11:10 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_try_mix.cpp:11:7:11:10 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_try_mix.cpp:11:12:11:15 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_try_mix.cpp:28:7:28:10 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_try_mix.cpp:28:7:28:10 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_try_mix.cpp:28:12:28:15 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_try_mix.cpp:48:5:48:8 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_try_mix.cpp:48:5:48:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ms_try_mix.cpp:48:10:48:13 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| newexpr.cpp:8:2:8:20 | Call [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| newexpr.cpp:8:2:8:20 | new [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| newexpr.cpp:8:2:8:20 | new [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -2321,21 +2321,21 @@ postWithInFlow
|
||||
| ops.cpp:26:31:26:53 | Call [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ops.cpp:26:31:26:53 | new [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ops.cpp:26:31:26:53 | new [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| parameterinitializer.cpp:8:5:8:10 | Got %d\n [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| parameterinitializer.cpp:8:12:8:21 | (char *)... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| parameterinitializer.cpp:8:12:8:21 | Got %d\n [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| parameterinitializer.cpp:8:12:8:21 | Got %d\n [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| parameterinitializer.cpp:8:12:8:21 | array to pointer conversion [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| parameterinitializer.cpp:25:5:25:8 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| parameterinitializer.cpp:25:5:25:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| parameterinitializer.cpp:27:3:27:6 | my_c [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| parameterinitializer.cpp:27:8:27:13 | my_c [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| parameterinitializer.cpp:27:3:27:6 | my_c [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| parameterinitializer.cpp:30:5:30:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| pointer_to_member.cpp:23:6:23:8 | obj [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| pointer_to_member.cpp:23:10:23:14 | obj [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| pointer_to_member.cpp:23:6:23:8 | obj [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| pointer_to_member.cpp:26:5:26:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| pointer_to_member.cpp:27:5:27:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| pointer_to_member.cpp:27:12:27:14 | obj [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| pointer_to_member.cpp:27:16:27:20 | obj [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| pointer_to_member.cpp:27:12:27:14 | obj [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| pointer_to_member.cpp:29:5:29:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| pruning.c:69:9:69:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| pruning.c:78:9:78:9 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -2585,9 +2585,9 @@ postWithInFlow
|
||||
| static_init_templates.cpp:3:2:3:4 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| static_init_templates.cpp:3:2:3:4 | ref [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| static_init_templates.cpp:18:7:18:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| static_init_templates.cpp:20:2:20:10 | a [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| static_init_templates.cpp:20:12:20:12 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| static_init_templates.cpp:20:12:20:12 | a [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| static_init_templates.cpp:20:12:20:12 | a [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| static_init_templates.cpp:21:2:21:4 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| static_init_templates.cpp:21:2:21:4 | val [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| static_init_templates.cpp:22:2:22:8 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -2629,8 +2629,8 @@ postWithInFlow
|
||||
| staticlocals.cpp:26:19:26:21 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| staticlocals.cpp:29:14:29:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| staticlocals.cpp:29:14:29:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| stmt_expr.cpp:13:16:13:16 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| stmt_expr.cpp:13:16:13:16 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| stmt_expr.cpp:13:18:13:19 | Argument this [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| stmt_expr.cpp:27:5:27:7 | ptr [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| stream_it.cpp:4:16:4:30 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| stream_it.cpp:5:14:5:28 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -2644,9 +2644,9 @@ postWithInFlow
|
||||
| stream_it.cpp:11:16:11:16 | (__range) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| stream_it.cpp:11:16:11:16 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| stream_it.cpp:11:16:11:16 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| stream_it.cpp:19:3:19:11 | xs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| stream_it.cpp:19:13:19:14 | (reference to) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| stream_it.cpp:19:13:19:14 | xs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| stream_it.cpp:19:13:19:14 | xs [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| stream_it.cpp:20:3:20:11 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| subscriptexpr.c:4:2:4:2 | i [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| switchbody.c:5:11:5:24 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
|
||||
@@ -136,7 +136,7 @@ useNotDominatedByDefinition
|
||||
| VacuousDestructorCall.cpp:2:29:2:29 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
|
||||
| misc.c:219:47:219:48 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | misc.c:219:5:219:26 | int assign_designated_init(someStruct*) | int assign_designated_init(someStruct*) |
|
||||
| static_init_templates.cpp:15:1:15:18 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | static_init_templates.cpp:15:1:15:18 | void MyClass::MyClass() | void MyClass::MyClass() |
|
||||
| try_catch.cpp:21:13:21:24 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | try_catch.cpp:19:6:19:23 | void throw_from_nonstmt(int) | void throw_from_nonstmt(int) |
|
||||
| try_catch.cpp:21:9:21:9 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | try_catch.cpp:19:6:19:23 | void throw_from_nonstmt(int) | void throw_from_nonstmt(int) |
|
||||
| vla.c:3:27:3:30 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | int main(int, char**) | int main(int, char**) |
|
||||
switchInstructionWithoutDefaultEdge
|
||||
notMarkedAsConflated
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
| file://:0:0:0:0 | __wchar_t * | PointerType | Wchar_t, WideCharType |
|
||||
| file://:0:0:0:0 | __wchar_t * | IteratorByPointer, PointerType | Wchar_t, WideCharType |
|
||||
| file://:0:0:0:0 | const __wchar_t | SpecifiedType | Wchar_t, WideCharType |
|
||||
| file://:0:0:0:0 | wchar_t | Wchar_t, WideCharType | |
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
| file://:0:0:0:0 | wchar_t | Wchar_t, WideCharType | |
|
||||
| file://:0:0:0:0 | wchar_t * | PointerType | CTypedefType, Wchar_t |
|
||||
| file://:0:0:0:0 | wchar_t * | IteratorByPointer, PointerType | CTypedefType, Wchar_t |
|
||||
| ms.c:2:24:2:30 | wchar_t | CTypedefType, Wchar_t | |
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
| char8_t | Char8Type | | | | |
|
||||
| char16_t | Char16Type | | | | |
|
||||
| char32_t | Char32Type | | | | |
|
||||
| char * | CharPointerType | | char | | |
|
||||
| char * | CharPointerType, IteratorByPointer | | char | | |
|
||||
| char *[3] | ArrayType | char * | char * | | |
|
||||
| char *[32] | ArrayType | char * | char * | | |
|
||||
| char *[] | ArrayType | char * | char * | | |
|
||||
@@ -48,7 +48,7 @@
|
||||
| const address | SpecifiedType | | address | | |
|
||||
| const address & | LValueReferenceType | | const address | | |
|
||||
| const char | SpecifiedType | | char | | |
|
||||
| const char * | PointerType | | const char | | |
|
||||
| const char * | IteratorByPointer, PointerType | | const char | | |
|
||||
| const char *[3] | ArrayType | const char * | const char * | | |
|
||||
| const char *[] | ArrayType | const char * | const char * | | |
|
||||
| const char[5] | ArrayType | const char | const char | | |
|
||||
@@ -65,7 +65,7 @@
|
||||
| float | FloatType | | | | |
|
||||
| float[3] | ArrayType | float | float | | |
|
||||
| int | IntType, MicrosoftInt32Type | | | | |
|
||||
| int * | IntPointerType | | int | | |
|
||||
| int * | IntPointerType, IteratorByPointer | | int | | |
|
||||
| int[4] | ArrayType | int | int | | |
|
||||
| int[8] | ArrayType | int | int | | |
|
||||
| int[10] | ArrayType | int | int | | |
|
||||
@@ -90,5 +90,5 @@
|
||||
| unsigned long long | LongLongType | | | | unsigned integral |
|
||||
| unsigned short | ShortType | | | | unsigned integral |
|
||||
| void | VoidType | | | | |
|
||||
| void * | VoidPointerType | | void | | |
|
||||
| void * | IteratorByPointer, VoidPointerType | | void | | |
|
||||
| wchar_t | Wchar_t, WideCharType | | | | |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-tests
|
||||
version: 0.0.2
|
||||
groups: [cpp, test]
|
||||
dependencies:
|
||||
codeql/cpp-all: "*"
|
||||
codeql/cpp-queries: "*"
|
||||
|
||||
@@ -1,47 +1,137 @@
|
||||
edges
|
||||
| test.cpp:26:29:26:29 | b | test.cpp:26:29:26:29 | b |
|
||||
| test.cpp:26:29:26:29 | b | test.cpp:27:2:27:2 | b |
|
||||
| test.cpp:30:34:30:34 | b | test.cpp:31:2:31:2 | b |
|
||||
| test.cpp:34:31:34:31 | b | test.cpp:34:31:34:31 | b |
|
||||
| test.cpp:34:31:34:31 | b | test.cpp:35:2:35:2 | b |
|
||||
| test.cpp:38:35:38:35 | d | test.cpp:38:35:38:35 | d |
|
||||
| test.cpp:38:35:38:35 | d | test.cpp:39:2:39:2 | d |
|
||||
| test.cpp:42:40:42:40 | d | test.cpp:43:2:43:2 | d |
|
||||
| test.cpp:46:37:46:37 | d | test.cpp:46:37:46:37 | d |
|
||||
| test.cpp:46:37:46:37 | d | test.cpp:47:2:47:2 | d |
|
||||
| test.cpp:50:31:50:31 | b | test.cpp:51:11:51:11 | b |
|
||||
| test.cpp:57:19:57:19 | d | test.cpp:26:29:26:29 | b |
|
||||
| test.cpp:57:19:57:19 | d | test.cpp:57:19:57:19 | ref arg d |
|
||||
| test.cpp:57:19:57:19 | ref arg d | test.cpp:58:25:58:25 | d |
|
||||
| test.cpp:57:19:57:19 | ref arg d | test.cpp:59:21:59:21 | d |
|
||||
| test.cpp:57:19:57:19 | ref arg d | test.cpp:61:22:61:22 | d |
|
||||
| test.cpp:57:19:57:19 | ref arg d | test.cpp:62:28:62:28 | d |
|
||||
| test.cpp:57:19:57:19 | ref arg d | test.cpp:63:24:63:24 | d |
|
||||
| test.cpp:57:19:57:19 | ref arg d | test.cpp:95:21:95:21 | d |
|
||||
| test.cpp:58:25:58:25 | d | test.cpp:30:34:30:34 | b |
|
||||
| test.cpp:59:21:59:21 | d | test.cpp:34:31:34:31 | b |
|
||||
| test.cpp:59:21:59:21 | d | test.cpp:59:21:59:21 | ref arg d |
|
||||
| test.cpp:59:21:59:21 | ref arg d | test.cpp:61:22:61:22 | d |
|
||||
| test.cpp:59:21:59:21 | ref arg d | test.cpp:62:28:62:28 | d |
|
||||
| test.cpp:59:21:59:21 | ref arg d | test.cpp:63:24:63:24 | d |
|
||||
| test.cpp:59:21:59:21 | ref arg d | test.cpp:95:21:95:21 | d |
|
||||
| test.cpp:61:22:61:22 | d | test.cpp:38:35:38:35 | d |
|
||||
| test.cpp:61:22:61:22 | d | test.cpp:61:22:61:22 | ref arg d |
|
||||
| test.cpp:61:22:61:22 | ref arg d | test.cpp:62:28:62:28 | d |
|
||||
| test.cpp:61:22:61:22 | ref arg d | test.cpp:63:24:63:24 | d |
|
||||
| test.cpp:61:22:61:22 | ref arg d | test.cpp:95:21:95:21 | d |
|
||||
| test.cpp:62:28:62:28 | d | test.cpp:42:40:42:40 | d |
|
||||
| test.cpp:63:24:63:24 | d | test.cpp:46:37:46:37 | d |
|
||||
| test.cpp:63:24:63:24 | d | test.cpp:63:24:63:24 | ref arg d |
|
||||
| test.cpp:63:24:63:24 | ref arg d | test.cpp:95:21:95:21 | d |
|
||||
| test.cpp:74:19:74:21 | dss | test.cpp:26:29:26:29 | b |
|
||||
| test.cpp:74:19:74:21 | dss | test.cpp:74:19:74:21 | ref arg dss |
|
||||
| test.cpp:74:19:74:21 | ref arg dss | test.cpp:75:25:75:27 | dss |
|
||||
| test.cpp:74:19:74:21 | ref arg dss | test.cpp:76:21:76:23 | dss |
|
||||
| test.cpp:74:19:74:21 | ref arg dss | test.cpp:96:21:96:23 | dss |
|
||||
| test.cpp:75:25:75:27 | dss | test.cpp:30:34:30:34 | b |
|
||||
| test.cpp:76:21:76:23 | dss | test.cpp:34:31:34:31 | b |
|
||||
| test.cpp:76:21:76:23 | dss | test.cpp:76:21:76:23 | ref arg dss |
|
||||
| test.cpp:76:21:76:23 | ref arg dss | test.cpp:96:21:96:23 | dss |
|
||||
| test.cpp:86:19:86:20 | d2 | test.cpp:26:29:26:29 | b |
|
||||
| test.cpp:86:19:86:20 | d2 | test.cpp:86:19:86:20 | ref arg d2 |
|
||||
| test.cpp:86:19:86:20 | ref arg d2 | test.cpp:87:25:87:26 | d2 |
|
||||
| test.cpp:86:19:86:20 | ref arg d2 | test.cpp:88:21:88:22 | d2 |
|
||||
| test.cpp:86:19:86:20 | ref arg d2 | test.cpp:90:22:90:23 | d2 |
|
||||
| test.cpp:86:19:86:20 | ref arg d2 | test.cpp:91:28:91:29 | d2 |
|
||||
| test.cpp:86:19:86:20 | ref arg d2 | test.cpp:92:24:92:25 | d2 |
|
||||
| test.cpp:87:25:87:26 | d2 | test.cpp:30:34:30:34 | b |
|
||||
| test.cpp:88:21:88:22 | d2 | test.cpp:34:31:34:31 | b |
|
||||
| test.cpp:88:21:88:22 | d2 | test.cpp:88:21:88:22 | ref arg d2 |
|
||||
| test.cpp:88:21:88:22 | ref arg d2 | test.cpp:90:22:90:23 | d2 |
|
||||
| test.cpp:88:21:88:22 | ref arg d2 | test.cpp:91:28:91:29 | d2 |
|
||||
| test.cpp:88:21:88:22 | ref arg d2 | test.cpp:92:24:92:25 | d2 |
|
||||
| test.cpp:90:22:90:23 | d2 | test.cpp:38:35:38:35 | d |
|
||||
| test.cpp:90:22:90:23 | d2 | test.cpp:90:22:90:23 | ref arg d2 |
|
||||
| test.cpp:90:22:90:23 | ref arg d2 | test.cpp:91:28:91:29 | d2 |
|
||||
| test.cpp:90:22:90:23 | ref arg d2 | test.cpp:92:24:92:25 | d2 |
|
||||
| test.cpp:91:28:91:29 | d2 | test.cpp:42:40:42:40 | d |
|
||||
| test.cpp:92:24:92:25 | d2 | test.cpp:46:37:46:37 | d |
|
||||
| test.cpp:95:21:95:21 | d | test.cpp:50:31:50:31 | b |
|
||||
| test.cpp:96:21:96:23 | dss | test.cpp:50:31:50:31 | b |
|
||||
nodes
|
||||
| test.cpp:26:29:26:29 | b | semmle.label | b |
|
||||
| test.cpp:26:29:26:29 | b | semmle.label | b |
|
||||
| test.cpp:27:2:27:2 | b | semmle.label | b |
|
||||
| test.cpp:30:34:30:34 | b | semmle.label | b |
|
||||
| test.cpp:31:2:31:2 | b | semmle.label | b |
|
||||
| test.cpp:34:31:34:31 | b | semmle.label | b |
|
||||
| test.cpp:34:31:34:31 | b | semmle.label | b |
|
||||
| test.cpp:35:2:35:2 | b | semmle.label | b |
|
||||
| test.cpp:38:35:38:35 | d | semmle.label | d |
|
||||
| test.cpp:38:35:38:35 | d | semmle.label | d |
|
||||
| test.cpp:39:2:39:2 | d | semmle.label | d |
|
||||
| test.cpp:42:40:42:40 | d | semmle.label | d |
|
||||
| test.cpp:43:2:43:2 | d | semmle.label | d |
|
||||
| test.cpp:46:37:46:37 | d | semmle.label | d |
|
||||
| test.cpp:46:37:46:37 | d | semmle.label | d |
|
||||
| test.cpp:47:2:47:2 | d | semmle.label | d |
|
||||
| test.cpp:50:31:50:31 | b | semmle.label | b |
|
||||
| test.cpp:51:11:51:11 | b | semmle.label | b |
|
||||
| test.cpp:57:19:57:19 | d | semmle.label | d |
|
||||
| test.cpp:57:19:57:19 | ref arg d | semmle.label | ref arg d |
|
||||
| test.cpp:58:25:58:25 | d | semmle.label | d |
|
||||
| test.cpp:59:21:59:21 | d | semmle.label | d |
|
||||
| test.cpp:59:21:59:21 | ref arg d | semmle.label | ref arg d |
|
||||
| test.cpp:61:22:61:22 | d | semmle.label | d |
|
||||
| test.cpp:61:22:61:22 | ref arg d | semmle.label | ref arg d |
|
||||
| test.cpp:62:28:62:28 | d | semmle.label | d |
|
||||
| test.cpp:63:24:63:24 | d | semmle.label | d |
|
||||
| test.cpp:63:24:63:24 | ref arg d | semmle.label | ref arg d |
|
||||
| test.cpp:74:19:74:21 | dss | semmle.label | dss |
|
||||
| test.cpp:74:19:74:21 | ref arg dss | semmle.label | ref arg dss |
|
||||
| test.cpp:75:25:75:27 | dss | semmle.label | dss |
|
||||
| test.cpp:76:21:76:23 | dss | semmle.label | dss |
|
||||
| test.cpp:76:21:76:23 | ref arg dss | semmle.label | ref arg dss |
|
||||
| test.cpp:86:19:86:20 | d2 | semmle.label | d2 |
|
||||
| test.cpp:86:19:86:20 | ref arg d2 | semmle.label | ref arg d2 |
|
||||
| test.cpp:87:25:87:26 | d2 | semmle.label | d2 |
|
||||
| test.cpp:88:21:88:22 | d2 | semmle.label | d2 |
|
||||
| test.cpp:88:21:88:22 | ref arg d2 | semmle.label | ref arg d2 |
|
||||
| test.cpp:90:22:90:23 | d2 | semmle.label | d2 |
|
||||
| test.cpp:90:22:90:23 | ref arg d2 | semmle.label | ref arg d2 |
|
||||
| test.cpp:91:28:91:29 | d2 | semmle.label | d2 |
|
||||
| test.cpp:92:24:92:25 | d2 | semmle.label | d2 |
|
||||
| test.cpp:95:21:95:21 | d | semmle.label | d |
|
||||
| test.cpp:96:21:96:23 | dss | semmle.label | dss |
|
||||
subpaths
|
||||
| test.cpp:57:19:57:19 | d | test.cpp:26:29:26:29 | b | test.cpp:26:29:26:29 | b | test.cpp:57:19:57:19 | ref arg d |
|
||||
| test.cpp:59:21:59:21 | d | test.cpp:34:31:34:31 | b | test.cpp:34:31:34:31 | b | test.cpp:59:21:59:21 | ref arg d |
|
||||
| test.cpp:61:22:61:22 | d | test.cpp:38:35:38:35 | d | test.cpp:38:35:38:35 | d | test.cpp:61:22:61:22 | ref arg d |
|
||||
| test.cpp:63:24:63:24 | d | test.cpp:46:37:46:37 | d | test.cpp:46:37:46:37 | d | test.cpp:63:24:63:24 | ref arg d |
|
||||
| test.cpp:74:19:74:21 | dss | test.cpp:26:29:26:29 | b | test.cpp:26:29:26:29 | b | test.cpp:74:19:74:21 | ref arg dss |
|
||||
| test.cpp:76:21:76:23 | dss | test.cpp:34:31:34:31 | b | test.cpp:34:31:34:31 | b | test.cpp:76:21:76:23 | ref arg dss |
|
||||
| test.cpp:86:19:86:20 | d2 | test.cpp:26:29:26:29 | b | test.cpp:26:29:26:29 | b | test.cpp:86:19:86:20 | ref arg d2 |
|
||||
| test.cpp:88:21:88:22 | d2 | test.cpp:34:31:34:31 | b | test.cpp:34:31:34:31 | b | test.cpp:88:21:88:22 | ref arg d2 |
|
||||
| test.cpp:90:22:90:23 | d2 | test.cpp:38:35:38:35 | d | test.cpp:38:35:38:35 | d | test.cpp:90:22:90:23 | ref arg d2 |
|
||||
#select
|
||||
| test.cpp:27:2:27:2 | b | test.cpp:57:19:57:19 | d | test.cpp:27:2:27:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:57:19:57:19 | d | here |
|
||||
| test.cpp:27:2:27:2 | b | test.cpp:74:19:74:21 | dss | test.cpp:27:2:27:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:74:19:74:21 | dss | here |
|
||||
| test.cpp:27:2:27:2 | b | test.cpp:86:19:86:20 | d2 | test.cpp:27:2:27:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:86:19:86:20 | d2 | here |
|
||||
| test.cpp:31:2:31:2 | b | test.cpp:57:19:57:19 | d | test.cpp:31:2:31:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:57:19:57:19 | d | here |
|
||||
| test.cpp:31:2:31:2 | b | test.cpp:58:25:58:25 | d | test.cpp:31:2:31:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:58:25:58:25 | d | here |
|
||||
| test.cpp:31:2:31:2 | b | test.cpp:74:19:74:21 | dss | test.cpp:31:2:31:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:74:19:74:21 | dss | here |
|
||||
| test.cpp:31:2:31:2 | b | test.cpp:75:25:75:27 | dss | test.cpp:31:2:31:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:75:25:75:27 | dss | here |
|
||||
| test.cpp:31:2:31:2 | b | test.cpp:86:19:86:20 | d2 | test.cpp:31:2:31:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:86:19:86:20 | d2 | here |
|
||||
| test.cpp:31:2:31:2 | b | test.cpp:87:25:87:26 | d2 | test.cpp:31:2:31:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:87:25:87:26 | d2 | here |
|
||||
| test.cpp:35:2:35:2 | b | test.cpp:57:19:57:19 | d | test.cpp:35:2:35:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:57:19:57:19 | d | here |
|
||||
| test.cpp:35:2:35:2 | b | test.cpp:59:21:59:21 | d | test.cpp:35:2:35:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:59:21:59:21 | d | here |
|
||||
| test.cpp:35:2:35:2 | b | test.cpp:74:19:74:21 | dss | test.cpp:35:2:35:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:74:19:74:21 | dss | here |
|
||||
| test.cpp:35:2:35:2 | b | test.cpp:76:21:76:23 | dss | test.cpp:35:2:35:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:76:21:76:23 | dss | here |
|
||||
| test.cpp:35:2:35:2 | b | test.cpp:86:19:86:20 | d2 | test.cpp:35:2:35:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:86:19:86:20 | d2 | here |
|
||||
| test.cpp:35:2:35:2 | b | test.cpp:88:21:88:22 | d2 | test.cpp:35:2:35:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:88:21:88:22 | d2 | here |
|
||||
|
||||
@@ -12,17 +12,17 @@ edges
|
||||
| search.c:22:24:22:28 | query | search.c:23:39:23:43 | query |
|
||||
| search.c:22:24:22:28 | query | search.c:23:39:23:43 | query |
|
||||
| search.c:22:24:22:28 | query | search.c:23:39:23:43 | query indirection |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:55:5:55:15 | raw_query |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:55:5:55:15 | raw_query |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:55:17:55:25 | raw_query |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:55:17:55:25 | raw_query |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:55:17:55:25 | raw_query indirection |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:55:17:55:25 | raw_query indirection |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:57:5:57:15 | raw_query |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:57:5:57:15 | raw_query |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:57:17:57:25 | raw_query |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:57:17:57:25 | raw_query |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:57:17:57:25 | raw_query indirection |
|
||||
| search.c:51:21:51:26 | call to getenv | search.c:57:17:57:25 | raw_query indirection |
|
||||
| search.c:55:5:55:15 | raw_query | search.c:14:24:14:28 | query |
|
||||
| search.c:55:17:55:25 | raw_query | search.c:14:24:14:28 | query |
|
||||
| search.c:55:17:55:25 | raw_query indirection | search.c:14:24:14:28 | *query |
|
||||
| search.c:57:5:57:15 | raw_query | search.c:22:24:22:28 | query |
|
||||
| search.c:57:17:57:25 | raw_query | search.c:22:24:22:28 | query |
|
||||
| search.c:57:17:57:25 | raw_query indirection | search.c:22:24:22:28 | *query |
|
||||
subpaths
|
||||
nodes
|
||||
@@ -44,9 +44,9 @@ nodes
|
||||
| search.c:23:39:23:43 | query indirection | semmle.label | query indirection |
|
||||
| search.c:51:21:51:26 | call to getenv | semmle.label | call to getenv |
|
||||
| search.c:51:21:51:26 | call to getenv | semmle.label | call to getenv |
|
||||
| search.c:55:5:55:15 | raw_query | semmle.label | raw_query |
|
||||
| search.c:55:17:55:25 | raw_query | semmle.label | raw_query |
|
||||
| search.c:55:17:55:25 | raw_query indirection | semmle.label | raw_query indirection |
|
||||
| search.c:57:5:57:15 | raw_query | semmle.label | raw_query |
|
||||
| search.c:57:17:57:25 | raw_query | semmle.label | raw_query |
|
||||
| search.c:57:17:57:25 | raw_query indirection | semmle.label | raw_query indirection |
|
||||
#select
|
||||
| search.c:17:8:17:12 | query | search.c:51:21:51:26 | call to getenv | search.c:17:8:17:12 | query | Cross-site scripting vulnerability due to $@. | search.c:51:21:51:26 | call to getenv | this query data |
|
||||
|
||||
@@ -6,11 +6,11 @@ edges
|
||||
| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data |
|
||||
| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data |
|
||||
| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data indirection |
|
||||
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:17:73:22 | data |
|
||||
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:17:73:22 | data |
|
||||
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data |
|
||||
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data |
|
||||
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data indirection |
|
||||
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data indirection |
|
||||
| test.cpp:73:17:73:22 | data | test.cpp:37:73:37:76 | data |
|
||||
| test.cpp:73:24:73:27 | data | test.cpp:37:73:37:76 | data |
|
||||
| test.cpp:73:24:73:27 | data indirection | test.cpp:37:73:37:76 | *data |
|
||||
subpaths
|
||||
nodes
|
||||
@@ -25,7 +25,7 @@ nodes
|
||||
| test.cpp:43:32:43:35 | data indirection | semmle.label | data indirection |
|
||||
| test.cpp:64:30:64:35 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:64:30:64:35 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:73:17:73:22 | data | semmle.label | data |
|
||||
| test.cpp:73:24:73:27 | data | semmle.label | data |
|
||||
| test.cpp:73:24:73:27 | data indirection | semmle.label | data indirection |
|
||||
#select
|
||||
| test.cpp:43:32:43:35 | data | test.cpp:64:30:64:35 | call to getenv | test.cpp:43:32:43:35 | data | The value of this argument may come from $@ and is being passed to LoadLibraryA | test.cpp:64:30:64:35 | call to getenv | call to getenv |
|
||||
|
||||
@@ -11,24 +11,50 @@ edges
|
||||
| test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command |
|
||||
| test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command |
|
||||
| test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command indirection |
|
||||
| test.cpp:42:7:42:16 | call to getenv | test.cpp:24:30:24:36 | command |
|
||||
| test.cpp:42:18:42:23 | call to getenv | test.cpp:42:7:42:16 | call to getenv |
|
||||
| test.cpp:42:18:42:23 | call to getenv | test.cpp:42:18:42:34 | call to getenv |
|
||||
| test.cpp:42:18:42:23 | call to getenv | test.cpp:42:18:42:34 | call to getenv indirection |
|
||||
| test.cpp:42:18:42:34 | (const char *)... | test.cpp:42:7:42:16 | call to getenv |
|
||||
| test.cpp:42:18:42:34 | (const char *)... | test.cpp:42:18:42:34 | call to getenv |
|
||||
| test.cpp:42:18:42:34 | (const char *)... | test.cpp:42:18:42:34 | call to getenv indirection |
|
||||
| test.cpp:42:18:42:34 | call to getenv | test.cpp:24:30:24:36 | command |
|
||||
| test.cpp:42:18:42:34 | call to getenv indirection | test.cpp:24:30:24:36 | *command |
|
||||
| test.cpp:43:7:43:16 | call to getenv | test.cpp:29:30:29:36 | command |
|
||||
| test.cpp:43:18:43:23 | call to getenv | test.cpp:43:7:43:16 | call to getenv |
|
||||
| test.cpp:43:18:43:23 | call to getenv | test.cpp:43:18:43:34 | call to getenv |
|
||||
| test.cpp:43:18:43:23 | call to getenv | test.cpp:43:18:43:34 | call to getenv indirection |
|
||||
| test.cpp:43:18:43:34 | (const char *)... | test.cpp:43:7:43:16 | call to getenv |
|
||||
| test.cpp:43:18:43:34 | (const char *)... | test.cpp:43:18:43:34 | call to getenv |
|
||||
| test.cpp:43:18:43:34 | (const char *)... | test.cpp:43:18:43:34 | call to getenv indirection |
|
||||
| test.cpp:43:18:43:34 | call to getenv | test.cpp:29:30:29:36 | command |
|
||||
| test.cpp:43:18:43:34 | call to getenv indirection | test.cpp:29:30:29:36 | *command |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | (const char *)... |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer indirection |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | (const char *)... |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data indirection |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | (const char *)... |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | (reference dereference) |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref indirection |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | (const char *)... |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 indirection |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | (const char *)... |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer indirection |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | (const char *)... |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data indirection |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | (const char *)... |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | (reference dereference) |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref indirection |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | (const char *)... |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 indirection |
|
||||
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | (const char *)... |
|
||||
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
|
||||
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer indirection |
|
||||
@@ -63,13 +89,13 @@ nodes
|
||||
| test.cpp:31:10:31:16 | command | semmle.label | command |
|
||||
| test.cpp:31:10:31:16 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:31:10:31:16 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:42:7:42:16 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:42:18:42:23 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:42:18:42:34 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:42:18:42:34 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:42:18:42:34 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:43:7:43:16 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:43:18:43:23 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:43:18:43:34 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:43:18:43:34 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:43:18:43:34 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:56:12:56:17 | buffer | semmle.label | buffer |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | semmle.label | fgets output argument |
|
||||
@@ -78,6 +104,29 @@ nodes
|
||||
| test.cpp:62:10:62:15 | buffer | semmle.label | buffer |
|
||||
| test.cpp:62:10:62:15 | buffer indirection | semmle.label | buffer indirection |
|
||||
| test.cpp:62:10:62:15 | buffer indirection | semmle.label | buffer indirection |
|
||||
| test.cpp:63:10:63:13 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:63:10:63:13 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:63:10:63:13 | data | semmle.label | data |
|
||||
| test.cpp:63:10:63:13 | data | semmle.label | data |
|
||||
| test.cpp:63:10:63:13 | data | semmle.label | data |
|
||||
| test.cpp:63:10:63:13 | data indirection | semmle.label | data indirection |
|
||||
| test.cpp:63:10:63:13 | data indirection | semmle.label | data indirection |
|
||||
| test.cpp:64:10:64:16 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:64:10:64:16 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:64:10:64:16 | (reference dereference) | semmle.label | (reference dereference) |
|
||||
| test.cpp:64:10:64:16 | (reference dereference) | semmle.label | (reference dereference) |
|
||||
| test.cpp:64:10:64:16 | dataref | semmle.label | dataref |
|
||||
| test.cpp:64:10:64:16 | dataref | semmle.label | dataref |
|
||||
| test.cpp:64:10:64:16 | dataref | semmle.label | dataref |
|
||||
| test.cpp:64:10:64:16 | dataref indirection | semmle.label | dataref indirection |
|
||||
| test.cpp:64:10:64:16 | dataref indirection | semmle.label | dataref indirection |
|
||||
| test.cpp:65:10:65:14 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:65:10:65:14 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:65:10:65:14 | data2 | semmle.label | data2 |
|
||||
| test.cpp:65:10:65:14 | data2 | semmle.label | data2 |
|
||||
| test.cpp:65:10:65:14 | data2 | semmle.label | data2 |
|
||||
| test.cpp:65:10:65:14 | data2 indirection | semmle.label | data2 indirection |
|
||||
| test.cpp:65:10:65:14 | data2 indirection | semmle.label | data2 indirection |
|
||||
| test.cpp:76:12:76:17 | buffer | semmle.label | buffer |
|
||||
| test.cpp:76:12:76:17 | fgets output argument | semmle.label | fgets output argument |
|
||||
| test.cpp:78:10:78:15 | (const char *)... | semmle.label | (const char *)... |
|
||||
@@ -103,6 +152,9 @@ nodes
|
||||
| test.cpp:26:10:26:16 | command | test.cpp:42:18:42:23 | call to getenv | test.cpp:26:10:26:16 | command | The value of this argument may come from $@ and is being passed to system | test.cpp:42:18:42:23 | call to getenv | call to getenv |
|
||||
| test.cpp:31:10:31:16 | command | test.cpp:43:18:43:23 | call to getenv | test.cpp:31:10:31:16 | command | The value of this argument may come from $@ and is being passed to system | test.cpp:43:18:43:23 | call to getenv | call to getenv |
|
||||
| test.cpp:62:10:62:15 | buffer | test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer | The value of this argument may come from $@ and is being passed to system | test.cpp:56:12:56:17 | buffer | buffer |
|
||||
| test.cpp:63:10:63:13 | data | test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data | The value of this argument may come from $@ and is being passed to system | test.cpp:56:12:56:17 | buffer | buffer |
|
||||
| test.cpp:64:10:64:16 | dataref | test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref | The value of this argument may come from $@ and is being passed to system | test.cpp:56:12:56:17 | buffer | buffer |
|
||||
| test.cpp:65:10:65:14 | data2 | test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 | The value of this argument may come from $@ and is being passed to system | test.cpp:56:12:56:17 | buffer | buffer |
|
||||
| test.cpp:78:10:78:15 | buffer | test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer | The value of this argument may come from $@ and is being passed to system | test.cpp:76:12:76:17 | buffer | buffer |
|
||||
| test.cpp:99:15:99:20 | buffer | test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer | The value of this argument may come from $@ and is being passed to LoadLibrary | test.cpp:98:17:98:22 | buffer | buffer |
|
||||
| test.cpp:107:15:107:20 | buffer | test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer | The value of this argument may come from $@ and is being passed to LoadLibrary | test.cpp:106:17:106:22 | buffer | buffer |
|
||||
|
||||
@@ -61,8 +61,8 @@ void testReferencePointer1()
|
||||
|
||||
system(buffer); // BAD
|
||||
system(data); // BAD
|
||||
system(dataref); // BAD [NOT DETECTED]
|
||||
system(data2); // BAD [NOT DETECTED]
|
||||
system(dataref); // BAD
|
||||
system(data2); // BAD
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -108,10 +108,45 @@ edges
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | (const char *)... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | (const char *)... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:10 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:10 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | (const char *)... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | (const char *)... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... indirection |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:17:136:18 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:17:136:18 | i4 |
|
||||
| argvLocal.c:117:15:117:16 | i3 indirection | argvLocal.c:9:25:9:31 | *correct |
|
||||
| argvLocal.c:117:15:117:16 | i3 indirection | argvLocal.c:117:15:117:16 | printWrapper output argument |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | (const char *)... |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | i4 |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | i4 |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | i4 indirection |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 |
|
||||
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 |
|
||||
@@ -317,6 +352,8 @@ nodes
|
||||
| argvLocal.c:121:9:121:10 | (const char *)... | semmle.label | (const char *)... |
|
||||
| argvLocal.c:121:9:121:10 | (const char *)... | semmle.label | (const char *)... |
|
||||
| argvLocal.c:121:9:121:10 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:121:9:121:10 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:121:9:121:10 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:121:9:121:10 | i4 indirection | semmle.label | i4 indirection |
|
||||
| argvLocal.c:121:9:121:10 | i4 indirection | semmle.label | i4 indirection |
|
||||
| argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 |
|
||||
|
||||
@@ -23,9 +23,9 @@ edges
|
||||
| globalVars.c:15:21:15:23 | val | globalVars.c:16:2:16:12 | Store |
|
||||
| globalVars.c:16:2:16:12 | Store | globalVars.c:9:7:9:11 | copy2 |
|
||||
| globalVars.c:19:25:19:27 | *str | globalVars.c:19:25:19:27 | ReturnIndirection |
|
||||
| globalVars.c:24:2:24:9 | argv | globalVars.c:11:22:11:25 | argv |
|
||||
| globalVars.c:24:11:24:14 | argv | globalVars.c:24:2:24:9 | argv |
|
||||
| globalVars.c:24:11:24:14 | argv | globalVars.c:24:2:24:9 | argv |
|
||||
| globalVars.c:24:11:24:14 | argv | globalVars.c:11:22:11:25 | argv |
|
||||
| globalVars.c:24:11:24:14 | argv | globalVars.c:24:11:24:14 | argv |
|
||||
| globalVars.c:24:11:24:14 | argv | globalVars.c:24:11:24:14 | argv |
|
||||
| globalVars.c:24:11:24:14 | argv | globalVars.c:24:11:24:14 | argv indirection |
|
||||
| globalVars.c:24:11:24:14 | argv | globalVars.c:24:11:24:14 | argv indirection |
|
||||
| globalVars.c:24:11:24:14 | argv indirection | globalVars.c:11:22:11:25 | *argv |
|
||||
@@ -37,13 +37,13 @@ edges
|
||||
| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy |
|
||||
| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy indirection |
|
||||
| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy indirection |
|
||||
| globalVars.c:30:15:30:18 | copy | globalVars.c:35:2:35:9 | copy |
|
||||
| globalVars.c:30:15:30:18 | copy | globalVars.c:35:11:35:14 | copy |
|
||||
| globalVars.c:30:15:30:18 | copy indirection | globalVars.c:19:25:19:27 | *str |
|
||||
| globalVars.c:30:15:30:18 | copy indirection | globalVars.c:30:15:30:18 | printWrapper output argument |
|
||||
| globalVars.c:30:15:30:18 | printWrapper output argument | globalVars.c:35:2:35:9 | copy |
|
||||
| globalVars.c:33:15:33:18 | copy | globalVars.c:35:2:35:9 | copy |
|
||||
| globalVars.c:35:2:35:9 | copy | globalVars.c:15:21:15:23 | val |
|
||||
| globalVars.c:35:11:35:14 | copy | globalVars.c:35:2:35:9 | copy |
|
||||
| globalVars.c:30:15:30:18 | printWrapper output argument | globalVars.c:35:11:35:14 | copy |
|
||||
| globalVars.c:33:15:33:18 | copy | globalVars.c:35:11:35:14 | copy |
|
||||
| globalVars.c:35:11:35:14 | copy | globalVars.c:15:21:15:23 | val |
|
||||
| globalVars.c:35:11:35:14 | copy | globalVars.c:35:11:35:14 | copy |
|
||||
| globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | (const char *)... |
|
||||
| globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | copy2 |
|
||||
| globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | copy2 indirection |
|
||||
@@ -85,7 +85,7 @@ nodes
|
||||
| globalVars.c:16:2:16:12 | Store | semmle.label | Store |
|
||||
| globalVars.c:19:25:19:27 | *str | semmle.label | *str |
|
||||
| globalVars.c:19:25:19:27 | ReturnIndirection | semmle.label | ReturnIndirection |
|
||||
| globalVars.c:24:2:24:9 | argv | semmle.label | argv |
|
||||
| globalVars.c:24:11:24:14 | argv | semmle.label | argv |
|
||||
| globalVars.c:24:11:24:14 | argv | semmle.label | argv |
|
||||
| globalVars.c:24:11:24:14 | argv | semmle.label | argv |
|
||||
| globalVars.c:24:11:24:14 | argv indirection | semmle.label | argv indirection |
|
||||
@@ -103,7 +103,7 @@ nodes
|
||||
| globalVars.c:30:15:30:18 | copy indirection | semmle.label | copy indirection |
|
||||
| globalVars.c:30:15:30:18 | printWrapper output argument | semmle.label | printWrapper output argument |
|
||||
| globalVars.c:33:15:33:18 | copy | semmle.label | copy |
|
||||
| globalVars.c:35:2:35:9 | copy | semmle.label | copy |
|
||||
| globalVars.c:35:11:35:14 | copy | semmle.label | copy |
|
||||
| globalVars.c:35:11:35:14 | copy | semmle.label | copy |
|
||||
| globalVars.c:38:9:38:13 | (const char *)... | semmle.label | (const char *)... |
|
||||
| globalVars.c:38:9:38:13 | (const char *)... | semmle.label | (const char *)... |
|
||||
|
||||
@@ -13,17 +13,15 @@ edges
|
||||
| test.c:155:22:155:27 | (unsigned int)... | test.c:157:9:157:9 | r |
|
||||
| test.cpp:6:5:6:12 | ReturnValue | test.cpp:24:11:24:18 | call to get_rand |
|
||||
| test.cpp:8:9:8:12 | call to rand | test.cpp:6:5:6:12 | ReturnValue |
|
||||
| test.cpp:13:2:13:6 | * ... [post update] | test.cpp:30:3:30:11 | & ... [post update] |
|
||||
| test.cpp:13:3:13:6 | dest [post update] | test.cpp:30:3:30:11 | & ... [post update] |
|
||||
| test.cpp:13:2:13:6 | * ... [post update] | test.cpp:30:13:30:14 | & ... [post update] |
|
||||
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:6 | * ... [post update] |
|
||||
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:3:13:6 | dest [post update] |
|
||||
| test.cpp:18:2:18:5 | (reference dereference) [post update] | test.cpp:36:3:36:11 | r [post update] |
|
||||
| test.cpp:18:2:18:5 | dest [post update] | test.cpp:36:3:36:11 | r [post update] |
|
||||
| test.cpp:13:10:13:13 | call to rand | test.cpp:30:13:30:14 | & ... [post update] |
|
||||
| test.cpp:18:2:18:5 | (reference dereference) [post update] | test.cpp:36:13:36:13 | r [post update] |
|
||||
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:5 | (reference dereference) [post update] |
|
||||
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:5 | dest [post update] |
|
||||
| test.cpp:18:9:18:12 | call to rand | test.cpp:36:13:36:13 | r [post update] |
|
||||
| test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r |
|
||||
| test.cpp:30:3:30:11 | & ... [post update] | test.cpp:31:7:31:7 | r |
|
||||
| test.cpp:36:3:36:11 | r [post update] | test.cpp:37:7:37:7 | r |
|
||||
| test.cpp:30:13:30:14 | & ... [post update] | test.cpp:31:7:31:7 | r |
|
||||
| test.cpp:36:13:36:13 | r [post update] | test.cpp:37:7:37:7 | r |
|
||||
| test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x |
|
||||
| test.cpp:98:10:98:13 | call to rand | test.cpp:102:10:102:10 | x |
|
||||
| test.cpp:137:10:137:13 | call to rand | test.cpp:146:9:146:9 | y |
|
||||
@@ -64,16 +62,14 @@ nodes
|
||||
| test.cpp:6:5:6:12 | ReturnValue | semmle.label | ReturnValue |
|
||||
| test.cpp:8:9:8:12 | call to rand | semmle.label | call to rand |
|
||||
| test.cpp:13:2:13:6 | * ... [post update] | semmle.label | * ... [post update] |
|
||||
| test.cpp:13:3:13:6 | dest [post update] | semmle.label | dest [post update] |
|
||||
| test.cpp:13:10:13:13 | call to rand | semmle.label | call to rand |
|
||||
| test.cpp:18:2:18:5 | (reference dereference) [post update] | semmle.label | (reference dereference) [post update] |
|
||||
| test.cpp:18:2:18:5 | dest [post update] | semmle.label | dest [post update] |
|
||||
| test.cpp:18:9:18:12 | call to rand | semmle.label | call to rand |
|
||||
| test.cpp:24:11:24:18 | call to get_rand | semmle.label | call to get_rand |
|
||||
| test.cpp:25:7:25:7 | r | semmle.label | r |
|
||||
| test.cpp:30:3:30:11 | & ... [post update] | semmle.label | & ... [post update] |
|
||||
| test.cpp:30:13:30:14 | & ... [post update] | semmle.label | & ... [post update] |
|
||||
| test.cpp:31:7:31:7 | r | semmle.label | r |
|
||||
| test.cpp:36:3:36:11 | r [post update] | semmle.label | r [post update] |
|
||||
| test.cpp:36:13:36:13 | r [post update] | semmle.label | r [post update] |
|
||||
| test.cpp:37:7:37:7 | r | semmle.label | r |
|
||||
| test.cpp:86:10:86:13 | call to rand | semmle.label | call to rand |
|
||||
| test.cpp:90:10:90:10 | x | semmle.label | x |
|
||||
|
||||
@@ -50,31 +50,31 @@ edges
|
||||
| test.cpp:237:24:237:29 | call to getenv | test.cpp:239:9:239:18 | (size_t)... |
|
||||
| test.cpp:237:24:237:29 | call to getenv | test.cpp:239:9:239:18 | local_size |
|
||||
| test.cpp:237:24:237:29 | call to getenv | test.cpp:239:9:239:18 | local_size |
|
||||
| test.cpp:237:24:237:29 | call to getenv | test.cpp:245:2:245:9 | local_size |
|
||||
| test.cpp:237:24:237:29 | call to getenv | test.cpp:247:2:247:8 | local_size |
|
||||
| test.cpp:237:24:237:29 | call to getenv | test.cpp:245:11:245:20 | local_size |
|
||||
| test.cpp:237:24:237:29 | call to getenv | test.cpp:247:10:247:19 | local_size |
|
||||
| test.cpp:237:24:237:37 | (const char *)... | test.cpp:239:9:239:18 | (size_t)... |
|
||||
| test.cpp:237:24:237:37 | (const char *)... | test.cpp:239:9:239:18 | local_size |
|
||||
| test.cpp:237:24:237:37 | (const char *)... | test.cpp:239:9:239:18 | local_size |
|
||||
| test.cpp:237:24:237:37 | (const char *)... | test.cpp:245:2:245:9 | local_size |
|
||||
| test.cpp:237:24:237:37 | (const char *)... | test.cpp:247:2:247:8 | local_size |
|
||||
| test.cpp:245:2:245:9 | local_size | test.cpp:224:23:224:23 | s |
|
||||
| test.cpp:247:2:247:8 | local_size | test.cpp:230:21:230:21 | s |
|
||||
| test.cpp:251:2:251:9 | (reference dereference) [post update] | test.cpp:289:8:289:15 | size [post update] |
|
||||
| test.cpp:251:2:251:9 | (reference dereference) [post update] | test.cpp:305:9:305:16 | size [post update] |
|
||||
| test.cpp:251:2:251:9 | out_size [post update] | test.cpp:289:8:289:15 | size [post update] |
|
||||
| test.cpp:251:2:251:9 | out_size [post update] | test.cpp:305:9:305:16 | size [post update] |
|
||||
| test.cpp:237:24:237:37 | (const char *)... | test.cpp:245:11:245:20 | local_size |
|
||||
| test.cpp:237:24:237:37 | (const char *)... | test.cpp:247:10:247:19 | local_size |
|
||||
| test.cpp:245:11:245:20 | local_size | test.cpp:224:23:224:23 | s |
|
||||
| test.cpp:247:10:247:19 | local_size | test.cpp:230:21:230:21 | s |
|
||||
| test.cpp:251:2:251:9 | (reference dereference) [post update] | test.cpp:289:17:289:20 | size [post update] |
|
||||
| test.cpp:251:2:251:9 | (reference dereference) [post update] | test.cpp:305:18:305:21 | size [post update] |
|
||||
| test.cpp:251:18:251:23 | call to getenv | test.cpp:251:2:251:9 | (reference dereference) [post update] |
|
||||
| test.cpp:251:18:251:23 | call to getenv | test.cpp:251:2:251:9 | out_size [post update] |
|
||||
| test.cpp:251:18:251:23 | call to getenv | test.cpp:289:17:289:20 | size [post update] |
|
||||
| test.cpp:251:18:251:23 | call to getenv | test.cpp:305:18:305:21 | size [post update] |
|
||||
| test.cpp:251:18:251:31 | (const char *)... | test.cpp:251:2:251:9 | (reference dereference) [post update] |
|
||||
| test.cpp:251:18:251:31 | (const char *)... | test.cpp:251:2:251:9 | out_size [post update] |
|
||||
| test.cpp:251:18:251:31 | (const char *)... | test.cpp:289:17:289:20 | size [post update] |
|
||||
| test.cpp:251:18:251:31 | (const char *)... | test.cpp:305:18:305:21 | size [post update] |
|
||||
| test.cpp:259:20:259:25 | call to getenv | test.cpp:263:11:263:29 | ... * ... |
|
||||
| test.cpp:259:20:259:25 | call to getenv | test.cpp:263:11:263:29 | ... * ... |
|
||||
| test.cpp:259:20:259:33 | (const char *)... | test.cpp:263:11:263:29 | ... * ... |
|
||||
| test.cpp:259:20:259:33 | (const char *)... | test.cpp:263:11:263:29 | ... * ... |
|
||||
| test.cpp:289:8:289:15 | size [post update] | test.cpp:291:11:291:28 | ... * ... |
|
||||
| test.cpp:289:8:289:15 | size [post update] | test.cpp:291:11:291:28 | ... * ... |
|
||||
| test.cpp:305:9:305:16 | size [post update] | test.cpp:308:10:308:27 | ... * ... |
|
||||
| test.cpp:305:9:305:16 | size [post update] | test.cpp:308:10:308:27 | ... * ... |
|
||||
| test.cpp:289:17:289:20 | size [post update] | test.cpp:291:11:291:28 | ... * ... |
|
||||
| test.cpp:289:17:289:20 | size [post update] | test.cpp:291:11:291:28 | ... * ... |
|
||||
| test.cpp:305:18:305:21 | size [post update] | test.cpp:308:10:308:27 | ... * ... |
|
||||
| test.cpp:305:18:305:21 | size [post update] | test.cpp:308:10:308:27 | ... * ... |
|
||||
subpaths
|
||||
nodes
|
||||
| test.cpp:40:21:40:24 | argv | semmle.label | argv |
|
||||
@@ -137,8 +137,8 @@ nodes
|
||||
| test.cpp:241:9:241:24 | call to get_tainted_size | semmle.label | call to get_tainted_size |
|
||||
| test.cpp:241:9:241:24 | call to get_tainted_size | semmle.label | call to get_tainted_size |
|
||||
| test.cpp:241:9:241:24 | call to get_tainted_size | semmle.label | call to get_tainted_size |
|
||||
| test.cpp:245:2:245:9 | local_size | semmle.label | local_size |
|
||||
| test.cpp:247:2:247:8 | local_size | semmle.label | local_size |
|
||||
| test.cpp:245:11:245:20 | local_size | semmle.label | local_size |
|
||||
| test.cpp:247:10:247:19 | local_size | semmle.label | local_size |
|
||||
| test.cpp:251:2:251:9 | (reference dereference) [post update] | semmle.label | (reference dereference) [post update] |
|
||||
| test.cpp:251:2:251:9 | out_size [post update] | semmle.label | out_size [post update] |
|
||||
| test.cpp:251:18:251:23 | call to getenv | semmle.label | call to getenv |
|
||||
@@ -148,11 +148,11 @@ nodes
|
||||
| test.cpp:263:11:263:29 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:263:11:263:29 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:263:11:263:29 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:289:8:289:15 | size [post update] | semmle.label | size [post update] |
|
||||
| test.cpp:289:17:289:20 | size [post update] | semmle.label | size [post update] |
|
||||
| test.cpp:291:11:291:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:291:11:291:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:291:11:291:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:305:9:305:16 | size [post update] | semmle.label | size [post update] |
|
||||
| test.cpp:305:18:305:21 | size [post update] | semmle.label | size [post update] |
|
||||
| test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... |
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
edges
|
||||
| test2.cpp:12:21:12:21 | v | test2.cpp:14:11:14:11 | v |
|
||||
| test2.cpp:12:21:12:21 | v | test2.cpp:14:11:14:11 | v |
|
||||
| test2.cpp:25:22:25:23 | & ... | test2.cpp:27:2:27:11 | v |
|
||||
| test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:27:2:27:11 | v |
|
||||
| test2.cpp:27:2:27:11 | v | test2.cpp:12:21:12:21 | v |
|
||||
| test2.cpp:25:22:25:23 | & ... | test2.cpp:27:13:27:13 | v |
|
||||
| test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:27:13:27:13 | v |
|
||||
| test2.cpp:27:13:27:13 | v | test2.cpp:12:21:12:21 | v |
|
||||
| test5.cpp:5:5:5:17 | ReturnValue | test5.cpp:17:6:17:18 | call to getTaintedInt |
|
||||
| test5.cpp:5:5:5:17 | ReturnValue | test5.cpp:17:6:17:18 | call to getTaintedInt |
|
||||
| test5.cpp:5:5:5:17 | ReturnValue | test5.cpp:18:6:18:18 | call to getTaintedInt |
|
||||
@@ -31,7 +31,7 @@ nodes
|
||||
| test2.cpp:14:11:14:11 | v | semmle.label | v |
|
||||
| test2.cpp:25:22:25:23 | & ... | semmle.label | & ... |
|
||||
| test2.cpp:25:22:25:23 | fscanf output argument | semmle.label | fscanf output argument |
|
||||
| test2.cpp:27:2:27:11 | v | semmle.label | v |
|
||||
| test2.cpp:27:13:27:13 | v | semmle.label | v |
|
||||
| test5.cpp:5:5:5:17 | ReturnValue | semmle.label | ReturnValue |
|
||||
| test5.cpp:9:7:9:9 | buf | semmle.label | buf |
|
||||
| test5.cpp:9:7:9:9 | gets output argument | semmle.label | gets output argument |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# This directory has its own qlpack for reasons detailed in commit 2550788598010fa2117274607c9d58f64f997f34
|
||||
name: codeql/cpp-tests-cwe-190-tainted
|
||||
version: 0.0.2
|
||||
groups: [cpp, test]
|
||||
dependencies:
|
||||
codeql/cpp-all: "*"
|
||||
codeql/cpp-queries: "*"
|
||||
|
||||
1
cpp/upgrades/CHANGELOG.md
Normal file
1
cpp/upgrades/CHANGELOG.md
Normal file
@@ -0,0 +1 @@
|
||||
## 0.0.4
|
||||
1
cpp/upgrades/change-notes/released/0.0.4.md
Normal file
1
cpp/upgrades/change-notes/released/0.0.4.md
Normal file
@@ -0,0 +1 @@
|
||||
## 0.0.4
|
||||
2
cpp/upgrades/codeql-pack.release.yml
Normal file
2
cpp/upgrades/codeql-pack.release.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.0.4
|
||||
@@ -1,4 +1,5 @@
|
||||
name: codeql/cpp-upgrades
|
||||
groups: cpp
|
||||
upgrades: .
|
||||
version: 0.0.2
|
||||
version: 0.0.4
|
||||
library: true
|
||||
|
||||
10
csharp/ql/consistency-queries/SsaConsistency.ql
Normal file
10
csharp/ql/consistency-queries/SsaConsistency.ql
Normal file
@@ -0,0 +1,10 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.dataflow.internal.SsaImplCommon::Consistency
|
||||
|
||||
class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition {
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
}
|
||||
1
csharp/ql/lib/CHANGELOG.md
Normal file
1
csharp/ql/lib/CHANGELOG.md
Normal file
@@ -0,0 +1 @@
|
||||
## 0.0.4
|
||||
1
csharp/ql/lib/change-notes/released/0.0.4.md
Normal file
1
csharp/ql/lib/change-notes/released/0.0.4.md
Normal file
@@ -0,0 +1 @@
|
||||
## 0.0.4
|
||||
2
csharp/ql/lib/codeql-pack.release.yml
Normal file
2
csharp/ql/lib/codeql-pack.release.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.0.4
|
||||
@@ -1,7 +1,8 @@
|
||||
name: codeql/csharp-all
|
||||
version: 0.0.2
|
||||
version: 0.0.4
|
||||
groups: csharp
|
||||
dbscheme: semmlecode.csharp.dbscheme
|
||||
extractor: csharp
|
||||
library: true
|
||||
dependencies:
|
||||
codeql/csharp-upgrades: 0.0.2
|
||||
codeql/csharp-upgrades: 0.0.3
|
||||
|
||||
@@ -634,3 +634,29 @@ class UncertainWriteDefinition extends WriteDefinition {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides a set of consistency queries. */
|
||||
module Consistency {
|
||||
abstract class RelevantDefinition extends Definition {
|
||||
abstract predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
);
|
||||
}
|
||||
|
||||
query predicate nonUniqueDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) {
|
||||
ssaDefReachesRead(v, def, bb, i) and
|
||||
not exists(unique(Definition def0 | ssaDefReachesRead(v, def0, bb, i)))
|
||||
}
|
||||
|
||||
query predicate readWithoutDef(SourceVariable v, BasicBlock bb, int i) {
|
||||
variableRead(bb, i, v, _) and
|
||||
not ssaDefReachesRead(v, _, bb, i)
|
||||
}
|
||||
|
||||
query predicate deadDef(RelevantDefinition def, SourceVariable v) {
|
||||
v = def.getSourceVariable() and
|
||||
not ssaDefReachesRead(_, def, _, _) and
|
||||
not phiHasInputFromBlock(_, def, _) and
|
||||
not uncertainWriteDefinitionInput(_, def)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,9 @@ private module Cached {
|
||||
}
|
||||
|
||||
private Expr getAChildExpr(ExprOrStmtParent parent) {
|
||||
result = parent.getAChildExpr() or
|
||||
result = parent.getAChildExpr() and
|
||||
not result = parent.(DeclarationWithGetSetAccessors).getExpressionBody()
|
||||
or
|
||||
result = parent.(AssignOperation).getExpandedAssignment()
|
||||
}
|
||||
|
||||
@@ -159,7 +161,7 @@ private module Cached {
|
||||
|
||||
private predicate parent(ControlFlowElement child, ExprOrStmtParent parent) {
|
||||
child = getAChild(parent) and
|
||||
not child instanceof Callable
|
||||
not child = any(Callable c).getBody()
|
||||
}
|
||||
|
||||
/** Holds if the enclosing body of `cfe` is `body`. */
|
||||
|
||||
@@ -383,7 +383,7 @@ class Parameterizable extends DotNet::Parameterizable, Declaration, @parameteriz
|
||||
override Parameter getParameter(int i) { params(result, _, _, i, _, this, _) }
|
||||
|
||||
/**
|
||||
* Gets the name of this parameter followed by its type, possibly prefixed
|
||||
* Gets the type of the parameter, possibly prefixed
|
||||
* with `out`, `ref`, or `params`, where appropriate.
|
||||
*/
|
||||
private string parameterTypeToString(int i) {
|
||||
|
||||
@@ -25,7 +25,7 @@ module ControlFlow {
|
||||
* Only nodes that can be reached from the callable entry point are included in
|
||||
* the CFG.
|
||||
*/
|
||||
class Node extends TNode {
|
||||
class Node extends TCfgNode {
|
||||
/** Gets a textual representation of this control flow node. */
|
||||
string toString() { none() }
|
||||
|
||||
@@ -268,13 +268,13 @@ module ControlFlow {
|
||||
|
||||
/** A node for a callable exit point, annotated with the type of exit. */
|
||||
class AnnotatedExitNode extends Node, TAnnotatedExitNode {
|
||||
private Callable c;
|
||||
private CfgScope scope;
|
||||
private boolean normal;
|
||||
|
||||
AnnotatedExitNode() { this = TAnnotatedExitNode(c, normal) }
|
||||
AnnotatedExitNode() { this = TAnnotatedExitNode(scope, normal) }
|
||||
|
||||
/** Gets the callable that this exit applies to. */
|
||||
Callable getCallable() { result = c }
|
||||
CfgScope getCallable() { result = scope }
|
||||
|
||||
/** Holds if this node represents a normal exit. */
|
||||
predicate isNormal() { normal = true }
|
||||
@@ -285,7 +285,7 @@ module ControlFlow {
|
||||
|
||||
override Callable getEnclosingCallable() { result = this.getCallable() }
|
||||
|
||||
override Location getLocation() { result = this.getCallable().getLocation() }
|
||||
override Location getLocation() { result = scope.getLocation() }
|
||||
|
||||
override string toString() {
|
||||
exists(string s |
|
||||
@@ -293,23 +293,27 @@ module ControlFlow {
|
||||
or
|
||||
normal = false and s = "abnormal"
|
||||
|
|
||||
result = "exit " + this.getCallable() + " (" + s + ")"
|
||||
result = "exit " + scope + " (" + s + ")"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** A node for a callable exit point. */
|
||||
class ExitNode extends Node, TExitNode {
|
||||
private CfgScope scope;
|
||||
|
||||
ExitNode() { this = TExitNode(scope) }
|
||||
|
||||
/** Gets the callable that this exit applies to. */
|
||||
Callable getCallable() { this = TExitNode(result) }
|
||||
Callable getCallable() { result = scope }
|
||||
|
||||
override BasicBlocks::ExitBlock getBasicBlock() { result = Node.super.getBasicBlock() }
|
||||
|
||||
override Callable getEnclosingCallable() { result = this.getCallable() }
|
||||
|
||||
override Location getLocation() { result = this.getCallable().getLocation() }
|
||||
override Location getLocation() { result = scope.getLocation() }
|
||||
|
||||
override string toString() { result = "exit " + this.getCallable().toString() }
|
||||
override string toString() { result = "exit " + scope }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -97,6 +97,24 @@ module ControlFlowTree {
|
||||
predicate idOf(Range_ x, int y) = equivalenceRelation(id/2)(x, y)
|
||||
}
|
||||
|
||||
/**
|
||||
* The `expr_parent_top_level_adjusted()` relation restricted to exclude relations
|
||||
* between properties and their getters' expression bodies in properties such as
|
||||
* `int P => 0`.
|
||||
*
|
||||
* This is in order to only associate the expression body with one CFG scope, namely
|
||||
* the getter (and not the declaration itself).
|
||||
*/
|
||||
private predicate expr_parent_top_level_adjusted2(
|
||||
Expr child, int i, @top_level_exprorstmt_parent parent
|
||||
) {
|
||||
expr_parent_top_level_adjusted(child, i, parent) and
|
||||
not exists(Getter g |
|
||||
g.getDeclaration() = parent and
|
||||
i = 0
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `first` is first executed when entering `scope`. */
|
||||
predicate scopeFirst(CfgScope scope, ControlFlowElement first) {
|
||||
scope =
|
||||
@@ -109,17 +127,23 @@ predicate scopeFirst(CfgScope scope, ControlFlowElement first) {
|
||||
else first(c.getBody(), first)
|
||||
)
|
||||
or
|
||||
expr_parent_top_level_adjusted(any(Expr e | first(e, first)), _, scope) and
|
||||
expr_parent_top_level_adjusted2(any(Expr e | first(e, first)), _, scope) and
|
||||
not scope instanceof Callable
|
||||
}
|
||||
|
||||
/** Holds if `scope` is exited when `last` finishes with completion `c`. */
|
||||
predicate scopeLast(Callable scope, ControlFlowElement last, Completion c) {
|
||||
last(scope.getBody(), last, c) and
|
||||
not c instanceof GotoCompletion
|
||||
predicate scopeLast(CfgScope scope, ControlFlowElement last, Completion c) {
|
||||
scope =
|
||||
any(Callable callable |
|
||||
last(callable.getBody(), last, c) and
|
||||
not c instanceof GotoCompletion
|
||||
or
|
||||
last(InitializerSplitting::lastConstructorInitializer(scope, _), last, c) and
|
||||
not callable.hasBody()
|
||||
)
|
||||
or
|
||||
last(InitializerSplitting::lastConstructorInitializer(scope, _), last, c) and
|
||||
not scope.hasBody()
|
||||
expr_parent_top_level_adjusted2(any(Expr e | last(e, last, c)), _, scope) and
|
||||
not scope instanceof Callable
|
||||
}
|
||||
|
||||
private class ConstructorTree extends ControlFlowTree, Constructor {
|
||||
|
||||
@@ -788,7 +788,7 @@ private module Cached {
|
||||
* The control flow graph is pruned for unreachable nodes.
|
||||
*/
|
||||
cached
|
||||
newtype TNode =
|
||||
newtype TCfgNode =
|
||||
TEntryNode(CfgScope scope) { succEntrySplits(scope, _, _, _) } or
|
||||
TAnnotatedExitNode(CfgScope scope, boolean normal) {
|
||||
exists(Reachability::SameSplitsBlock b, SuccessorType t | b.isReachable(_) |
|
||||
@@ -807,7 +807,7 @@ private module Cached {
|
||||
|
||||
/** Gets a successor node of a given flow type, if any. */
|
||||
cached
|
||||
TNode getASuccessor(TNode pred, SuccessorType t) {
|
||||
TCfgNode getASuccessor(TCfgNode pred, SuccessorType t) {
|
||||
// Callable entry node -> callable body
|
||||
exists(ControlFlowElement succElement, Splits succSplits, CfgScope scope |
|
||||
result = TElementNode(succElement, succSplits) and
|
||||
@@ -943,4 +943,9 @@ module Consistency {
|
||||
strictcount(getASuccessor(node, t)) > 1 and
|
||||
successor = getASuccessor(node, t)
|
||||
}
|
||||
|
||||
query predicate deadEnd(Node node) {
|
||||
not node instanceof TExitNode and
|
||||
not exists(getASuccessor(node, _))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -634,3 +634,29 @@ class UncertainWriteDefinition extends WriteDefinition {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides a set of consistency queries. */
|
||||
module Consistency {
|
||||
abstract class RelevantDefinition extends Definition {
|
||||
abstract predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
);
|
||||
}
|
||||
|
||||
query predicate nonUniqueDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) {
|
||||
ssaDefReachesRead(v, def, bb, i) and
|
||||
not exists(unique(Definition def0 | ssaDefReachesRead(v, def0, bb, i)))
|
||||
}
|
||||
|
||||
query predicate readWithoutDef(SourceVariable v, BasicBlock bb, int i) {
|
||||
variableRead(bb, i, v, _) and
|
||||
not ssaDefReachesRead(v, _, bb, i)
|
||||
}
|
||||
|
||||
query predicate deadDef(RelevantDefinition def, SourceVariable v) {
|
||||
v = def.getSourceVariable() and
|
||||
not ssaDefReachesRead(_, def, _, _) and
|
||||
not phiHasInputFromBlock(_, def, _) and
|
||||
not uncertainWriteDefinitionInput(_, def)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,6 +289,7 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
exists(Node n | node.asNode() = n |
|
||||
config.isBarrier(n)
|
||||
@@ -307,11 +308,23 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sourceNode(NodeEx node, Configuration config) { config.isSource(node.asNode()) }
|
||||
private predicate sourceNode(NodeEx node, Configuration config) {
|
||||
config.isSource(node.asNode()) and
|
||||
not fullBarrier(node, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) }
|
||||
|
||||
/** Provides the relevant barriers for a step from `node1` to `node2`. */
|
||||
pragma[inline]
|
||||
private predicate stepFilter(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
@@ -320,16 +333,14 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.asNode() = n and
|
||||
node2.isImplicitReadNode(n, false)
|
||||
node2.isImplicitReadNode(n, false) and
|
||||
not fullBarrier(node1, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -342,16 +353,14 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.isImplicitReadNode(n, true) and
|
||||
node2.asNode() = n
|
||||
node2.asNode() = n and
|
||||
not fullBarrier(node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -363,10 +372,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
@@ -380,16 +386,14 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
|
||||
private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) {
|
||||
read(node1.asNode(), c, node2.asNode())
|
||||
read(node1.asNode(), c, node2.asNode()) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
node2.isImplicitReadNode(n, true) and
|
||||
@@ -402,7 +406,8 @@ private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
read(_, tc.getContent(), _, config)
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -451,63 +456,59 @@ private module Stage1 {
|
||||
* argument in a call.
|
||||
*/
|
||||
predicate fwdFlow(NodeEx node, Cc cc, Configuration config) {
|
||||
not fullBarrier(node, config) and
|
||||
(
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config) and
|
||||
not outBarrier(mid, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config) and
|
||||
not inBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -547,7 +548,8 @@ private module Stage1 {
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
viableReturnPosOutEx(call, pos, out)
|
||||
viableReturnPosOutEx(call, pos, out) and
|
||||
not fullBarrier(out, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -773,6 +775,7 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
@@ -1019,12 +1022,14 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,9 +1147,8 @@ private module Stage2 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1159,9 +1163,8 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1171,10 +1174,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1230,6 +1231,11 @@ private module Stage2 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -1306,7 +1312,7 @@ private module Stage2 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -1341,9 +1347,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1353,9 +1358,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1365,9 +1369,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1707,12 +1710,14 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1837,9 +1842,8 @@ private module Stage3 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1854,9 +1858,8 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1866,10 +1869,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1925,6 +1926,11 @@ private module Stage3 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2001,7 +2007,7 @@ private module Stage3 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2036,9 +2042,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2048,9 +2053,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2060,9 +2064,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2473,12 +2476,14 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2603,9 +2608,8 @@ private module Stage4 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2620,9 +2624,8 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2632,10 +2635,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2691,6 +2692,11 @@ private module Stage4 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2767,7 +2773,7 @@ private module Stage4 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2802,9 +2808,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2814,9 +2819,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2826,9 +2830,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -289,6 +289,7 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
exists(Node n | node.asNode() = n |
|
||||
config.isBarrier(n)
|
||||
@@ -307,11 +308,23 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sourceNode(NodeEx node, Configuration config) { config.isSource(node.asNode()) }
|
||||
private predicate sourceNode(NodeEx node, Configuration config) {
|
||||
config.isSource(node.asNode()) and
|
||||
not fullBarrier(node, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) }
|
||||
|
||||
/** Provides the relevant barriers for a step from `node1` to `node2`. */
|
||||
pragma[inline]
|
||||
private predicate stepFilter(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
@@ -320,16 +333,14 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.asNode() = n and
|
||||
node2.isImplicitReadNode(n, false)
|
||||
node2.isImplicitReadNode(n, false) and
|
||||
not fullBarrier(node1, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -342,16 +353,14 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.isImplicitReadNode(n, true) and
|
||||
node2.asNode() = n
|
||||
node2.asNode() = n and
|
||||
not fullBarrier(node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -363,10 +372,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
@@ -380,16 +386,14 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
|
||||
private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) {
|
||||
read(node1.asNode(), c, node2.asNode())
|
||||
read(node1.asNode(), c, node2.asNode()) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
node2.isImplicitReadNode(n, true) and
|
||||
@@ -402,7 +406,8 @@ private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
read(_, tc.getContent(), _, config)
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -451,63 +456,59 @@ private module Stage1 {
|
||||
* argument in a call.
|
||||
*/
|
||||
predicate fwdFlow(NodeEx node, Cc cc, Configuration config) {
|
||||
not fullBarrier(node, config) and
|
||||
(
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config) and
|
||||
not outBarrier(mid, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config) and
|
||||
not inBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -547,7 +548,8 @@ private module Stage1 {
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
viableReturnPosOutEx(call, pos, out)
|
||||
viableReturnPosOutEx(call, pos, out) and
|
||||
not fullBarrier(out, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -773,6 +775,7 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
@@ -1019,12 +1022,14 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,9 +1147,8 @@ private module Stage2 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1159,9 +1163,8 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1171,10 +1174,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1230,6 +1231,11 @@ private module Stage2 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -1306,7 +1312,7 @@ private module Stage2 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -1341,9 +1347,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1353,9 +1358,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1365,9 +1369,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1707,12 +1710,14 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1837,9 +1842,8 @@ private module Stage3 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1854,9 +1858,8 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1866,10 +1869,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1925,6 +1926,11 @@ private module Stage3 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2001,7 +2007,7 @@ private module Stage3 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2036,9 +2042,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2048,9 +2053,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2060,9 +2064,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2473,12 +2476,14 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2603,9 +2608,8 @@ private module Stage4 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2620,9 +2624,8 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2632,10 +2635,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2691,6 +2692,11 @@ private module Stage4 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2767,7 +2773,7 @@ private module Stage4 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2802,9 +2808,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2814,9 +2819,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2826,9 +2830,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -289,6 +289,7 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
exists(Node n | node.asNode() = n |
|
||||
config.isBarrier(n)
|
||||
@@ -307,11 +308,23 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sourceNode(NodeEx node, Configuration config) { config.isSource(node.asNode()) }
|
||||
private predicate sourceNode(NodeEx node, Configuration config) {
|
||||
config.isSource(node.asNode()) and
|
||||
not fullBarrier(node, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) }
|
||||
|
||||
/** Provides the relevant barriers for a step from `node1` to `node2`. */
|
||||
pragma[inline]
|
||||
private predicate stepFilter(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
@@ -320,16 +333,14 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.asNode() = n and
|
||||
node2.isImplicitReadNode(n, false)
|
||||
node2.isImplicitReadNode(n, false) and
|
||||
not fullBarrier(node1, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -342,16 +353,14 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.isImplicitReadNode(n, true) and
|
||||
node2.asNode() = n
|
||||
node2.asNode() = n and
|
||||
not fullBarrier(node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -363,10 +372,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
@@ -380,16 +386,14 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
|
||||
private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) {
|
||||
read(node1.asNode(), c, node2.asNode())
|
||||
read(node1.asNode(), c, node2.asNode()) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
node2.isImplicitReadNode(n, true) and
|
||||
@@ -402,7 +406,8 @@ private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
read(_, tc.getContent(), _, config)
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -451,63 +456,59 @@ private module Stage1 {
|
||||
* argument in a call.
|
||||
*/
|
||||
predicate fwdFlow(NodeEx node, Cc cc, Configuration config) {
|
||||
not fullBarrier(node, config) and
|
||||
(
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config) and
|
||||
not outBarrier(mid, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config) and
|
||||
not inBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -547,7 +548,8 @@ private module Stage1 {
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
viableReturnPosOutEx(call, pos, out)
|
||||
viableReturnPosOutEx(call, pos, out) and
|
||||
not fullBarrier(out, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -773,6 +775,7 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
@@ -1019,12 +1022,14 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,9 +1147,8 @@ private module Stage2 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1159,9 +1163,8 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1171,10 +1174,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1230,6 +1231,11 @@ private module Stage2 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -1306,7 +1312,7 @@ private module Stage2 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -1341,9 +1347,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1353,9 +1358,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1365,9 +1369,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1707,12 +1710,14 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1837,9 +1842,8 @@ private module Stage3 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1854,9 +1858,8 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1866,10 +1869,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1925,6 +1926,11 @@ private module Stage3 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2001,7 +2007,7 @@ private module Stage3 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2036,9 +2042,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2048,9 +2053,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2060,9 +2064,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2473,12 +2476,14 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2603,9 +2608,8 @@ private module Stage4 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2620,9 +2624,8 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2632,10 +2635,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2691,6 +2692,11 @@ private module Stage4 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2767,7 +2773,7 @@ private module Stage4 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2802,9 +2808,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2814,9 +2819,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2826,9 +2830,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -289,6 +289,7 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
exists(Node n | node.asNode() = n |
|
||||
config.isBarrier(n)
|
||||
@@ -307,11 +308,23 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sourceNode(NodeEx node, Configuration config) { config.isSource(node.asNode()) }
|
||||
private predicate sourceNode(NodeEx node, Configuration config) {
|
||||
config.isSource(node.asNode()) and
|
||||
not fullBarrier(node, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) }
|
||||
|
||||
/** Provides the relevant barriers for a step from `node1` to `node2`. */
|
||||
pragma[inline]
|
||||
private predicate stepFilter(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
@@ -320,16 +333,14 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.asNode() = n and
|
||||
node2.isImplicitReadNode(n, false)
|
||||
node2.isImplicitReadNode(n, false) and
|
||||
not fullBarrier(node1, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -342,16 +353,14 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.isImplicitReadNode(n, true) and
|
||||
node2.asNode() = n
|
||||
node2.asNode() = n and
|
||||
not fullBarrier(node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -363,10 +372,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
@@ -380,16 +386,14 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
|
||||
private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) {
|
||||
read(node1.asNode(), c, node2.asNode())
|
||||
read(node1.asNode(), c, node2.asNode()) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
node2.isImplicitReadNode(n, true) and
|
||||
@@ -402,7 +406,8 @@ private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
read(_, tc.getContent(), _, config)
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -451,63 +456,59 @@ private module Stage1 {
|
||||
* argument in a call.
|
||||
*/
|
||||
predicate fwdFlow(NodeEx node, Cc cc, Configuration config) {
|
||||
not fullBarrier(node, config) and
|
||||
(
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config) and
|
||||
not outBarrier(mid, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config) and
|
||||
not inBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -547,7 +548,8 @@ private module Stage1 {
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
viableReturnPosOutEx(call, pos, out)
|
||||
viableReturnPosOutEx(call, pos, out) and
|
||||
not fullBarrier(out, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -773,6 +775,7 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
@@ -1019,12 +1022,14 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,9 +1147,8 @@ private module Stage2 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1159,9 +1163,8 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1171,10 +1174,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1230,6 +1231,11 @@ private module Stage2 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -1306,7 +1312,7 @@ private module Stage2 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -1341,9 +1347,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1353,9 +1358,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1365,9 +1369,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1707,12 +1710,14 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1837,9 +1842,8 @@ private module Stage3 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1854,9 +1858,8 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1866,10 +1869,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1925,6 +1926,11 @@ private module Stage3 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2001,7 +2007,7 @@ private module Stage3 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2036,9 +2042,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2048,9 +2053,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2060,9 +2064,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2473,12 +2476,14 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2603,9 +2608,8 @@ private module Stage4 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2620,9 +2624,8 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2632,10 +2635,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2691,6 +2692,11 @@ private module Stage4 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2767,7 +2773,7 @@ private module Stage4 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2802,9 +2808,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2814,9 +2819,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2826,9 +2830,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -289,6 +289,7 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
exists(Node n | node.asNode() = n |
|
||||
config.isBarrier(n)
|
||||
@@ -307,11 +308,23 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sourceNode(NodeEx node, Configuration config) { config.isSource(node.asNode()) }
|
||||
private predicate sourceNode(NodeEx node, Configuration config) {
|
||||
config.isSource(node.asNode()) and
|
||||
not fullBarrier(node, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sinkNode(NodeEx node, Configuration config) { config.isSink(node.asNode()) }
|
||||
|
||||
/** Provides the relevant barriers for a step from `node1` to `node2`. */
|
||||
pragma[inline]
|
||||
private predicate stepFilter(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow in one local step from `node1` to `node2`.
|
||||
*/
|
||||
@@ -320,16 +333,14 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.asNode() = n and
|
||||
node2.isImplicitReadNode(n, false)
|
||||
node2.isImplicitReadNode(n, false) and
|
||||
not fullBarrier(node1, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -342,16 +353,14 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config)
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
exists(Node n |
|
||||
config.allowImplicitRead(n, _) and
|
||||
node1.isImplicitReadNode(n, true) and
|
||||
node2.asNode() = n
|
||||
node2.asNode() = n and
|
||||
not fullBarrier(node2, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -363,10 +372,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
@@ -380,16 +386,14 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
not outBarrier(node1, config) and
|
||||
not inBarrier(node2, config) and
|
||||
not fullBarrier(node1, config) and
|
||||
not fullBarrier(node2, config) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
}
|
||||
|
||||
private predicate read(NodeEx node1, Content c, NodeEx node2, Configuration config) {
|
||||
read(node1.asNode(), c, node2.asNode())
|
||||
read(node1.asNode(), c, node2.asNode()) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
node2.isImplicitReadNode(n, true) and
|
||||
@@ -402,7 +406,8 @@ private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
read(_, tc.getContent(), _, config)
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -451,63 +456,59 @@ private module Stage1 {
|
||||
* argument in a call.
|
||||
*/
|
||||
predicate fwdFlow(NodeEx node, Cc cc, Configuration config) {
|
||||
not fullBarrier(node, config) and
|
||||
(
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
sourceNode(node, config) and
|
||||
if hasSourceCallCtx(config) then cc = true else cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true and
|
||||
not fullBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
localFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, cc, config) and
|
||||
additionalLocalFlowStep(mid, node, config)
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
jumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
exists(NodeEx mid |
|
||||
fwdFlow(mid, _, config) and
|
||||
additionalJumpStep(mid, node, config) and
|
||||
cc = false
|
||||
)
|
||||
or
|
||||
// store
|
||||
exists(NodeEx mid |
|
||||
useFieldFlow(config) and
|
||||
fwdFlow(mid, cc, config) and
|
||||
store(mid, _, node, _, config) and
|
||||
not outBarrier(mid, config)
|
||||
)
|
||||
or
|
||||
// read
|
||||
exists(Content c |
|
||||
fwdFlowRead(c, node, cc, config) and
|
||||
fwdFlowConsCand(c, config) and
|
||||
not inBarrier(node, config)
|
||||
)
|
||||
or
|
||||
// flow into a callable
|
||||
exists(NodeEx arg |
|
||||
fwdFlow(arg, _, config) and
|
||||
viableParamArgEx(_, node, arg) and
|
||||
cc = true
|
||||
)
|
||||
or
|
||||
// flow out of a callable
|
||||
exists(DataFlowCall call |
|
||||
fwdFlowOut(call, node, false, config) and
|
||||
cc = false
|
||||
or
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
fwdFlowOutFromArg(call, node, config) and
|
||||
fwdFlowIsEntered(call, cc, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -547,7 +548,8 @@ private module Stage1 {
|
||||
private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc, Configuration config) {
|
||||
exists(ReturnPosition pos |
|
||||
fwdFlowReturnPosition(pos, cc, config) and
|
||||
viableReturnPosOutEx(call, pos, out)
|
||||
viableReturnPosOutEx(call, pos, out) and
|
||||
not fullBarrier(out, config)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -773,6 +775,7 @@ private module Stage1 {
|
||||
* Holds if flow may enter through `p` and reach a return node making `p` a
|
||||
* candidate for the origin of a summary.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
|
||||
exists(ReturnKindExt kind |
|
||||
throughFlowNodeCand(p, config) and
|
||||
@@ -1019,12 +1022,14 @@ private module Stage2 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1142,9 +1147,8 @@ private module Stage2 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1159,9 +1163,8 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1171,10 +1174,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1230,6 +1231,11 @@ private module Stage2 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -1306,7 +1312,7 @@ private module Stage2 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -1341,9 +1347,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1353,9 +1358,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1365,9 +1369,8 @@ private module Stage2 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1707,12 +1710,14 @@ private module Stage3 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1837,9 +1842,8 @@ private module Stage3 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1854,9 +1858,8 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1866,10 +1869,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1925,6 +1926,11 @@ private module Stage3 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2001,7 +2007,7 @@ private module Stage3 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2036,9 +2042,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2048,9 +2053,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2060,9 +2064,8 @@ private module Stage3 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2473,12 +2476,14 @@ private module Stage4 {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate flowThroughOutOfCall(
|
||||
DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, Configuration config
|
||||
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
|
||||
Configuration config
|
||||
) {
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, pragma[only_bind_into](config)) and
|
||||
PrevStage::callMayFlowThroughRev(call, pragma[only_bind_into](config)) and
|
||||
PrevStage::parameterMayFlowThrough(_, ret.getEnclosingCallable(), _,
|
||||
pragma[only_bind_into](config))
|
||||
pragma[only_bind_into](config)) and
|
||||
ccc.matchesCall(call)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2603,9 +2608,8 @@ private module Stage4 {
|
||||
exists(ArgNodeEx arg, boolean allowsFieldFlow |
|
||||
fwdFlow(arg, outercc, argAp, ap, config) and
|
||||
flowIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
innercc = getCallContextCall(call, p.getEnclosingCallable(), outercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2620,9 +2624,8 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
ccOut = getCallContextReturn(inner, call, innercc) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2632,10 +2635,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(RetNodeEx ret, boolean allowsFieldFlow, CcCall ccc |
|
||||
fwdFlow(ret, ccc, apSome(argAp), ap, config) and
|
||||
flowThroughOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
ccc.matchesCall(call)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughOutOfCall(call, ccc, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2691,6 +2692,11 @@ private module Stage4 {
|
||||
callMayFlowThroughFwd(call, pragma[only_bind_into](config))
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate returnNodeMayFlowThrough(RetNodeEx ret, Ap ap, Configuration config) {
|
||||
fwdFlow(ret, any(CcCall ccc), apSome(_), ap, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` with access path `ap` is part of a path from a source to a
|
||||
* sink in the configuration `config`.
|
||||
@@ -2767,7 +2773,7 @@ private module Stage4 {
|
||||
// flow out of a callable
|
||||
revFlowOut(_, node, _, _, ap, config) and
|
||||
toReturn = true and
|
||||
if fwdFlow(node, any(CcCall ccc), apSome(_), ap, config)
|
||||
if returnNodeMayFlowThrough(node, ap, config)
|
||||
then returnAp = apSome(ap)
|
||||
else returnAp = apNone()
|
||||
}
|
||||
@@ -2802,9 +2808,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(NodeEx out, boolean allowsFieldFlow |
|
||||
revFlow(out, toReturn, returnAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2814,9 +2819,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, false, returnAp, ap, config) and
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowIntoCall(_, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2826,9 +2830,8 @@ private module Stage4 {
|
||||
) {
|
||||
exists(ParamNodeEx p, boolean allowsFieldFlow |
|
||||
revFlow(p, true, apSome(returnAp), ap, config) and
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
flowThroughIntoCall(call, arg, p, allowsFieldFlow, config) and
|
||||
if allowsFieldFlow = false then ap instanceof ApNil else any()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,19 @@ private import tainttracking1.TaintTrackingParameter::Private
|
||||
private import tainttracking1.TaintTrackingParameter::Public
|
||||
|
||||
module Consistency {
|
||||
private newtype TConsistencyConfiguration = MkConsistencyConfiguration()
|
||||
|
||||
/** A class for configuring the consistency queries. */
|
||||
class ConsistencyConfiguration extends TConsistencyConfiguration {
|
||||
string toString() { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */
|
||||
predicate postWithInFlowExclude(Node n) { none() }
|
||||
|
||||
/** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */
|
||||
predicate argHasPostUpdateExclude(ArgumentNode n) { none() }
|
||||
}
|
||||
|
||||
private class RelevantNode extends Node {
|
||||
RelevantNode() {
|
||||
this instanceof ArgumentNode or
|
||||
@@ -164,7 +177,7 @@ module Consistency {
|
||||
|
||||
query predicate argHasPostUpdate(ArgumentNode n, string msg) {
|
||||
not hasPost(n) and
|
||||
not isImmutableOrUnobservable(n) and
|
||||
not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and
|
||||
msg = "ArgumentNode is missing PostUpdateNode."
|
||||
}
|
||||
|
||||
@@ -177,6 +190,7 @@ module Consistency {
|
||||
isPostUpdateNode(n) and
|
||||
not clearsContent(n, _) and
|
||||
simpleLocalFlowStep(_, n) and
|
||||
not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and
|
||||
msg = "PostUpdateNode should not be the target of local flow."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1947,15 +1947,6 @@ class Unit extends TUnit {
|
||||
string toString() { result = "unit" }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `n` does not require a `PostUpdateNode` as it either cannot be
|
||||
* modified or its modification cannot be observed, for example if it is a
|
||||
* freshly created object that is not saved in a variable.
|
||||
*
|
||||
* This predicate is only used for consistency checks.
|
||||
*/
|
||||
predicate isImmutableOrUnobservable(Node n) { none() }
|
||||
|
||||
class LambdaCallKind = Unit;
|
||||
|
||||
/** Holds if `creation` is an expression that creates a delegate for `c`. */
|
||||
|
||||
@@ -85,6 +85,9 @@ module Public {
|
||||
/** Holds if this stack contains summary component `c`. */
|
||||
predicate contains(SummaryComponent c) { c = this.drop(_).head() }
|
||||
|
||||
/** Gets the bottom element of this stack. */
|
||||
SummaryComponent bottom() { result = this.drop(this.length() - 1).head() }
|
||||
|
||||
/** Gets a textual representation of this stack. */
|
||||
string toString() {
|
||||
exists(SummaryComponent head, SummaryComponentStack tail |
|
||||
@@ -124,6 +127,38 @@ module Public {
|
||||
SummaryComponentStack return(ReturnKind rk) { result = singleton(SummaryComponent::return(rk)) }
|
||||
}
|
||||
|
||||
private predicate noComponentSpecificCsv(SummaryComponent sc) {
|
||||
not exists(getComponentSpecificCsv(sc))
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this component used for flow summaries. */
|
||||
private string getComponentCsv(SummaryComponent sc) {
|
||||
result = getComponentSpecificCsv(sc)
|
||||
or
|
||||
noComponentSpecificCsv(sc) and
|
||||
(
|
||||
exists(int i | sc = TParameterSummaryComponent(i) and result = "Parameter[" + i + "]")
|
||||
or
|
||||
exists(int i | sc = TArgumentSummaryComponent(i) and result = "Argument[" + i + "]")
|
||||
or
|
||||
sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue"
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this stack used for flow summaries. */
|
||||
string getComponentStackCsv(SummaryComponentStack stack) {
|
||||
exists(SummaryComponent head, SummaryComponentStack tail |
|
||||
head = stack.head() and
|
||||
tail = stack.tail() and
|
||||
result = getComponentCsv(head) + " of " + getComponentStackCsv(tail)
|
||||
)
|
||||
or
|
||||
exists(SummaryComponent c |
|
||||
stack = TSingletonSummaryComponentStack(c) and
|
||||
result = getComponentCsv(c)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A class that exists for QL technical reasons only (the IPA type used
|
||||
* to represent component stacks needs to be bounded).
|
||||
@@ -197,6 +232,8 @@ module Private {
|
||||
or
|
||||
tail.(RequiredSummaryComponentStack).required(TParameterSummaryComponent(_)) and
|
||||
head = thisParam()
|
||||
or
|
||||
derivedFluentFlowPush(_, _, _, head, tail, _)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -210,7 +247,7 @@ module Private {
|
||||
c.propagatesFlow(output, input, preservesValue) and
|
||||
preservesValue = true and
|
||||
isCallbackParameter(input) and
|
||||
isContentOfArgument(output)
|
||||
isContentOfArgument(output, _)
|
||||
or
|
||||
// flow from the receiver of a callback into the instance-parameter
|
||||
exists(SummaryComponentStack s, SummaryComponentStack callbackRef |
|
||||
@@ -222,16 +259,81 @@ module Private {
|
||||
output = TConsSummaryComponentStack(thisParam(), input) and
|
||||
preservesValue = true
|
||||
)
|
||||
or
|
||||
exists(SummaryComponentStack arg, SummaryComponentStack return |
|
||||
derivedFluentFlow(c, input, arg, return, preservesValue)
|
||||
|
|
||||
arg.length() = 1 and
|
||||
output = return
|
||||
or
|
||||
exists(SummaryComponent head, SummaryComponentStack tail |
|
||||
derivedFluentFlowPush(c, input, arg, head, tail, 0) and
|
||||
output = SummaryComponentStack::push(head, tail)
|
||||
)
|
||||
)
|
||||
or
|
||||
// Chain together summaries where values get passed into callbacks along the way
|
||||
exists(SummaryComponentStack mid, boolean preservesValue1, boolean preservesValue2 |
|
||||
c.propagatesFlow(input, mid, preservesValue1) and
|
||||
c.propagatesFlow(mid, output, preservesValue2) and
|
||||
mid.drop(mid.length() - 2) =
|
||||
SummaryComponentStack::push(TParameterSummaryComponent(_),
|
||||
SummaryComponentStack::singleton(TArgumentSummaryComponent(_))) and
|
||||
preservesValue = preservesValue1.booleanAnd(preservesValue2)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `c` has a flow summary from `input` to `arg`, where `arg`
|
||||
* writes to (contents of) the `i`th argument, and `c` has a
|
||||
* value-preserving flow summary from the `i`th argument to a return value
|
||||
* (`return`).
|
||||
*
|
||||
* In such a case, we derive flow from `input` to (contents of) the return
|
||||
* value.
|
||||
*
|
||||
* As an example, this simplifies modeling of fluent methods:
|
||||
* for `StringBuilder.append(x)` with a specified value flow from qualifier to
|
||||
* return value and taint flow from argument 0 to the qualifier, then this
|
||||
* allows us to infer taint flow from argument 0 to the return value.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate derivedFluentFlow(
|
||||
SummarizedCallable c, SummaryComponentStack input, SummaryComponentStack arg,
|
||||
SummaryComponentStack return, boolean preservesValue
|
||||
) {
|
||||
exists(int i |
|
||||
summary(c, input, arg, preservesValue) and
|
||||
isContentOfArgument(arg, i) and
|
||||
summary(c, SummaryComponentStack::singleton(TArgumentSummaryComponent(i)), return, true) and
|
||||
return.bottom() = TReturnSummaryComponent(_)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate derivedFluentFlowPush(
|
||||
SummarizedCallable c, SummaryComponentStack input, SummaryComponentStack arg,
|
||||
SummaryComponent head, SummaryComponentStack tail, int i
|
||||
) {
|
||||
derivedFluentFlow(c, input, arg, tail, _) and
|
||||
head = arg.drop(i).head() and
|
||||
i = arg.length() - 2
|
||||
or
|
||||
exists(SummaryComponent head0, SummaryComponentStack tail0 |
|
||||
derivedFluentFlowPush(c, input, arg, head0, tail0, i + 1) and
|
||||
head = arg.drop(i).head() and
|
||||
tail = SummaryComponentStack::push(head0, tail0)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isCallbackParameter(SummaryComponentStack s) {
|
||||
s.head() = TParameterSummaryComponent(_) and exists(s.tail())
|
||||
}
|
||||
|
||||
private predicate isContentOfArgument(SummaryComponentStack s) {
|
||||
s.head() = TContentSummaryComponent(_) and isContentOfArgument(s.tail())
|
||||
private predicate isContentOfArgument(SummaryComponentStack s, int i) {
|
||||
s.head() = TContentSummaryComponent(_) and isContentOfArgument(s.tail(), i)
|
||||
or
|
||||
s = TSingletonSummaryComponentStack(TArgumentSummaryComponent(_))
|
||||
s = TSingletonSummaryComponentStack(TArgumentSummaryComponent(i))
|
||||
}
|
||||
|
||||
private predicate outputState(SummarizedCallable c, SummaryComponentStack s) {
|
||||
@@ -508,9 +610,14 @@ module Private {
|
||||
* node, and back out to `p`.
|
||||
*/
|
||||
predicate summaryAllowParameterReturnInSelf(ParamNode p) {
|
||||
exists(SummarizedCallable c, int i |
|
||||
c.clearsContent(i, _) and
|
||||
p.isParameterOf(c, i)
|
||||
exists(SummarizedCallable c, int i | p.isParameterOf(c, i) |
|
||||
c.clearsContent(i, _)
|
||||
or
|
||||
exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents |
|
||||
summary(c, inputContents, outputContents, _) and
|
||||
inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(i)) and
|
||||
outputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(i))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -534,22 +641,6 @@ module Private {
|
||||
preservesValue = false and not summary(c, inputContents, outputContents, true)
|
||||
)
|
||||
or
|
||||
// If flow through a method updates a parameter from some input A, and that
|
||||
// parameter also is returned through B, then we'd like a combined flow from A
|
||||
// to B as well. As an example, this simplifies modeling of fluent methods:
|
||||
// for `StringBuilder.append(x)` with a specified value flow from qualifier to
|
||||
// return value and taint flow from argument 0 to the qualifier, then this
|
||||
// allows us to infer taint flow from argument 0 to the return value.
|
||||
succ instanceof ParamNode and
|
||||
summaryPostUpdateNode(pred, succ) and
|
||||
preservesValue = true
|
||||
or
|
||||
// Similarly we would like to chain together summaries where values get passed
|
||||
// into callbacks along the way.
|
||||
pred instanceof ArgNode and
|
||||
summaryPostUpdateNode(succ, pred) and
|
||||
preservesValue = true
|
||||
or
|
||||
exists(SummarizedCallable c, int i |
|
||||
pred.(ParamNode).isParameterOf(c, i) and
|
||||
succ = summaryNode(c, TSummaryNodeClearsContentState(i, _)) and
|
||||
@@ -911,18 +1002,31 @@ module Private {
|
||||
module TestOutput {
|
||||
/** A flow summary to include in the `summary/3` query predicate. */
|
||||
abstract class RelevantSummarizedCallable extends SummarizedCallable {
|
||||
/** Gets the string representation of this callable used by `summary/3`. */
|
||||
string getFullString() { result = this.toString() }
|
||||
/** Gets the string representation of this callable used by `summary/1`. */
|
||||
abstract string getCallableCsv();
|
||||
}
|
||||
|
||||
/** A query predicate for outputting flow summaries in QL tests. */
|
||||
query predicate summary(string callable, string flow, boolean preservesValue) {
|
||||
/** Render the kind in the format used in flow summaries. */
|
||||
private string renderKind(boolean preservesValue) {
|
||||
preservesValue = true and result = "value"
|
||||
or
|
||||
preservesValue = false and result = "taint"
|
||||
}
|
||||
|
||||
/**
|
||||
* A query predicate for outputting flow summaries in semi-colon separated format in QL tests.
|
||||
* The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind",
|
||||
* ext is hardcoded to empty.
|
||||
*/
|
||||
query predicate summary(string csv) {
|
||||
exists(
|
||||
RelevantSummarizedCallable c, SummaryComponentStack input, SummaryComponentStack output
|
||||
RelevantSummarizedCallable c, SummaryComponentStack input, SummaryComponentStack output,
|
||||
boolean preservesValue
|
||||
|
|
||||
callable = c.getFullString() and
|
||||
c.propagatesFlow(input, output, preservesValue) and
|
||||
flow = input + " -> " + output
|
||||
csv =
|
||||
c.getCallableCsv() + ";;" + getComponentStackCsv(input) + ";" +
|
||||
getComponentStackCsv(output) + ";" + renderKind(preservesValue)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,6 +138,26 @@ SummaryComponent interpretComponentSpecific(string c) {
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the textual representation of the content in the format used for flow summaries. */
|
||||
private string getContentSpecificCsv(Content c) {
|
||||
c = TElementContent() and result = "Element"
|
||||
or
|
||||
exists(Field f | c = TFieldContent(f) and result = "Field[" + f.getQualifiedName() + "]")
|
||||
or
|
||||
exists(Property p | c = TPropertyContent(p) and result = "Property[" + p.getQualifiedName() + "]")
|
||||
}
|
||||
|
||||
/** Gets the textual representation of a summary component in the format used for flow summaries. */
|
||||
string getComponentSpecificCsv(SummaryComponent sc) {
|
||||
exists(Content c | sc = TContentSummaryComponent(c) and result = getContentSpecificCsv(c))
|
||||
or
|
||||
exists(ReturnKind rk |
|
||||
sc = TReturnSummaryComponent(rk) and
|
||||
result = "ReturnValue[" + rk + "]" and
|
||||
not rk instanceof NormalReturnKind
|
||||
)
|
||||
}
|
||||
|
||||
class SourceOrSinkElement = Element;
|
||||
|
||||
/** Gets the return kind corresponding to specification `"ReturnValue"`. */
|
||||
|
||||
@@ -171,7 +171,8 @@ private module SourceVariableImpl {
|
||||
def.getTarget() = lv and
|
||||
lv.isRef() and
|
||||
lv = v.getAssignable() and
|
||||
bb.getNode(i) = def.getAControlFlowNode()
|
||||
bb.getNode(i) = def.getAControlFlowNode() and
|
||||
not def.getAssignment() instanceof LocalVariableDeclAndInitExpr
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -634,3 +634,29 @@ class UncertainWriteDefinition extends WriteDefinition {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides a set of consistency queries. */
|
||||
module Consistency {
|
||||
abstract class RelevantDefinition extends Definition {
|
||||
abstract predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
);
|
||||
}
|
||||
|
||||
query predicate nonUniqueDef(RelevantDefinition def, SourceVariable v, BasicBlock bb, int i) {
|
||||
ssaDefReachesRead(v, def, bb, i) and
|
||||
not exists(unique(Definition def0 | ssaDefReachesRead(v, def0, bb, i)))
|
||||
}
|
||||
|
||||
query predicate readWithoutDef(SourceVariable v, BasicBlock bb, int i) {
|
||||
variableRead(bb, i, v, _) and
|
||||
not ssaDefReachesRead(v, _, bb, i)
|
||||
}
|
||||
|
||||
query predicate deadDef(RelevantDefinition def, SourceVariable v) {
|
||||
v = def.getSourceVariable() and
|
||||
not ssaDefReachesRead(_, def, _, _) and
|
||||
not phiHasInputFromBlock(_, def, _) and
|
||||
not uncertainWriteDefinitionInput(_, def)
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user