Compare commits

...

227 Commits

Author SHA1 Message Date
Dave Bartolomeo
8344d5a376 Merge pull request #11133 from github/release-prep/2.11.3
Release preparation for version 2.11.3
2022-11-04 22:50:41 -04:00
Dave Bartolomeo
013b7eff1c Apply suggestions from code review
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2022-11-04 18:46:32 -04:00
github-actions[bot]
508327235a Release preparation for version 2.11.3 2022-11-04 20:16:23 +00:00
Dave Bartolomeo
649c3af98a Merge pull request #11127 from github/henrymercer/fix-atm-pr-checks
ATM: Fix CodeQL pack workspace references
2022-11-04 12:19:42 -04:00
Arthur Baars
58c0e65542 Merge pull request #11129 from aibaars/improve-weak-crypto
Ruby: Improve weak crypto query
2022-11-04 16:31:55 +01:00
Arthur Baars
98f4c29913 Ruby: weak crypto: do not report weak hash algorithms
Weak hash algorithms such as MD5 and SHA1 are often
used in non security sensitive contexts and reporting
all uses is far too noisy.
2022-11-04 15:58:50 +01:00
Erik Krogh Kristensen
418d632738 Merge pull request #11123 from erik-krogh/stableCI-followup-2
fix typo in compile-queries workflow
2022-11-04 15:48:27 +01:00
AlexDenisov
c7da814bca Merge pull request #11122 from github/alexdenisov/make-macos-sed-happy
Swift: make sed on macos happy
2022-11-04 15:45:06 +01:00
Paolo Tranquilli
0370d1a1ba Merge pull request #11008 from github/redsun82/swift-macos-integration-tests
Swift: rework workflows
2022-11-04 15:44:42 +01:00
Tom Hvitved
05bf86acb6 Merge pull request #11126 from hvitved/cpp/position-overrides
C++: Let `(Indirect|Direct)Position` be sub classes of `Position`
2022-11-04 15:35:27 +01:00
AlexDenisov
0260ecfbdb Merge branch 'main' into alexdenisov/make-macos-sed-happy 2022-11-04 15:17:08 +01:00
Henry Mercer
0b9588bf9e ATM: Add test pack to workspace 2022-11-04 14:07:14 +00:00
Henry Mercer
3e863a539a ATM: Fix CodeQL pack workspace references
This fixes the
[ATM PR checks](https://github.com/github/codeql/actions/runs/3392995797/jobs/5639827326)
breaking on main as a result of
https://github.com/github/codeql/pull/11004.
2022-11-04 14:03:34 +00:00
Tom Hvitved
95835b8297 C++: Let (Indirect|Direct)Position be sub classes of Position 2022-11-04 14:31:18 +01:00
erik-krogh
def9b5e2ce fix typo in compile-queries workflow 2022-11-04 13:58:29 +01:00
Erik Krogh Kristensen
265838aa2c Merge pull request #11117 from erik-krogh/stableCI-followup
fix merge-base compilation when running directly on main
2022-11-04 13:56:41 +01:00
AlexDenisov
476bbfbdb7 Update qltest.sh 2022-11-04 13:04:24 +01:00
Erik Krogh Kristensen
91b33f72b5 update name and comment to reflect that it also runs on rc branches 2022-11-04 12:50:18 +01:00
Tamás Vajk
545dd8b8d8 Merge pull request #11106 from tamasvajk/kotlin-binop-ext
Kotlin: Extract extension binary operators
2022-11-04 12:41:06 +01:00
Paolo Tranquilli
2bec4479e7 Merge pull request #11029 from github/redsun82/swift-filtered-debugging
Swift: add possibility to run the extractor under an env-specified tool
2022-11-04 11:44:11 +01:00
erik-krogh
47289a4d33 fix merge-base compilation when running directly on main 2022-11-04 11:28:56 +01:00
Erik Krogh Kristensen
ec87a932b8 Merge pull request #11078 from erik-krogh/stableCI
add workflow that checks compilation of all queries with the latest stable release
2022-11-04 11:21:23 +01:00
Erik Krogh Kristensen
c82d8cbacc Merge pull request #11013 from erik-krogh/sndCmd
JS: second-order-command-injection
2022-11-04 10:58:50 +01:00
Paolo Tranquilli
daa4e99a2f Swift: fix executable permissions
These were broken by a merge done in the github UI.
2022-11-04 10:47:47 +01:00
Paolo Tranquilli
fdde84ac35 Merge branch 'main' into redsun82/swift-filtered-debugging 2022-11-04 10:42:48 +01:00
Paolo Tranquilli
858ae3dab4 Merge pull request #11116 from github/redsun82/swift-expect-failure-in-qltest
Swift: allow expecting failure in qltest.sh
2022-11-04 10:40:41 +01:00
Tom Hvitved
2f8dcdd602 Merge pull request #10933 from hvitved/csharp/fix-flow-into-phis
C#: Fix flow steps into phi/uncertain def nodes
2022-11-04 10:28:09 +01:00
Tom Hvitved
587e6739d9 Merge pull request #11060 from hvitved/dataflow/path-node-reach-charpred
Data flow: Restrict public `PathNode`s to those that may reach a sink
2022-11-04 10:17:09 +01:00
Paolo Tranquilli
231f2238c1 Swift: fix wrong test names 2022-11-04 10:06:57 +01:00
Paolo Tranquilli
4cfe11c319 Swift: allow expecting failure in qltest.sh 2022-11-04 10:03:00 +01:00
Anders Schack-Mulligen
331b8c0144 Merge pull request #10904 from aschackmull/java/joinorders
Java: Fix some join-orders.
2022-11-04 09:24:31 +01:00
Nora Dimitrijević
924f999aa8 Merge pull request #11104 from github/swift/webviewjoinorder 2022-11-03 16:44:17 +01:00
Erik Krogh Kristensen
1f51bd4594 add dash in description
Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com>
2022-11-03 16:24:59 +01:00
Tamas Vajk
16cb4c5aaa Kotlin: Extract extension binary operators 2022-11-03 16:11:23 +01:00
Tamas Vajk
70561cabaf Kotlin: Add test cases for extension binary operators 2022-11-03 16:10:32 +01:00
Tom Hvitved
1711efcc47 C#: Update expected test output 2022-11-03 15:52:30 +01:00
Tom Hvitved
a533c95640 C++: Update expected test output 2022-11-03 15:52:30 +01:00
Tom Hvitved
d3488da0c2 Data flow: Sync files 2022-11-03 15:52:30 +01:00
Tom Hvitved
cc87d2e38b Data flow: Restrict public PathNodes to those that may reach a sink 2022-11-03 15:52:30 +01:00
Nora Dimitrijević
0e67100cad Swift: fix bad join order in WebView/JsExportedSource
The `getName = getName` join was happening too early,
before the methods themselves have been enumerated.
2022-11-03 15:30:04 +01:00
Henry Mercer
12ab95668c Merge pull request #11098 from github/henrymercer/summary-metrics-consistent-naming
Summary metrics: Improve consistency of naming
2022-11-03 14:05:23 +00:00
Henry Mercer
8060b30cce Merge pull request #11099 from github/henrymercer/atm-labeler
Add ATM to labeler
2022-11-03 13:49:35 +00:00
Erik Krogh Kristensen
5918e0184c quote $CHANNEL
Co-authored-by: Arthur Baars <aibaars@github.com>
2022-11-03 14:17:44 +01:00
Mathias Vorreiter Pedersen
1ca7c5b97d Merge pull request #11091 from JarLob/assign
Fix AV Rule 76
2022-11-03 13:06:10 +00:00
erik-krogh
96ec54e5be fix minor issues in qhelp 2022-11-03 14:01:58 +01:00
erik-krogh
b5666888b1 rewrite @description of second-order-command-injection 2022-11-03 14:00:29 +01:00
erik-krogh
83a8b1afb8 use fetch-codeql action 2022-11-03 13:49:15 +01:00
Henry Mercer
7ce4629b12 Add ATM to labeler 2022-11-03 11:55:19 +00:00
Henry Mercer
dd264c6dfb Consistently mention language in metric names
This improves consistency between the lines of code queries and the
number of successfully extracted files queries.
2022-11-03 11:44:10 +00:00
Mathias Vorreiter Pedersen
ad0b36a0c9 C++: Add change note. 2022-11-03 11:41:38 +00:00
Henry Mercer
c60d071239 Lowercase "lines" 2022-11-03 11:40:22 +00:00
Tony Torralba
83caf01778 Merge pull request #11096 from atorralba/atorralba/swift/unit
Swift: Move the Unit class to its own file
2022-11-03 12:00:57 +01:00
erik-krogh
3159b3d9a1 swift: fix unused variable 2022-11-03 11:20:15 +01:00
erik-krogh
f9195d194b go: make sure the source/sink have the same type as the edges relation 2022-11-03 11:20:15 +01:00
erik-krogh
c9fcef2608 go: add a precision tag to go/examples/deferinloop 2022-11-03 11:20:15 +01:00
erik-krogh
1ec204987d go: remove precision from metric queries 2022-11-03 11:20:15 +01:00
erik-krogh
fc811bd33d add workflow that checks compilation of all queries with the latest stable release 2022-11-03 11:20:12 +01:00
Tony Torralba
978ed03e9c Move the Unit class to its own file 2022-11-03 11:19:41 +01:00
Chris Smowton
44b0f1921f Merge pull request #11090 from smowton/smowton/fix/value-parameter-label-external-class
Kotlin: drop same-file requirement for overridden parameter labels
2022-11-03 10:17:33 +00:00
Asger F
8502939b65 Merge pull request #11081 from asgerf/ql/dependency-paths
QL4QL: Add DependencyPath.ql query
2022-11-03 10:17:45 +01:00
Mathias Vorreiter Pedersen
01f3150a70 Merge pull request #11092 from hvitved/swift/avoid-deprecated-ssa-predicates
Swift: Avoid calls to deprecated SSA predicates
2022-11-03 09:03:47 +00:00
Asger F
fbcdb53d72 QL: Add option to follow 'cached' dependencies 2022-11-03 09:43:56 +01:00
Paolo Tranquilli
7e0a7d8b71 Swift: fix third-party action commit 2022-11-03 09:20:58 +01:00
Paolo Tranquilli
73131cef9e Merge branch 'main' into redsun82/swift-macos-integration-tests 2022-11-03 09:19:07 +01:00
Tom Hvitved
4e3fcc3235 Swift: Avoid calls to deprecated SSA predicates 2022-11-03 09:03:20 +01:00
Dave Bartolomeo
499f20f6e8 Merge pull request #11004 from dbartol/dbartol/use-workspace-versions 2022-11-02 20:02:48 -04:00
JarLob
3317223e19 Fix AV Rule 76 2022-11-02 22:50:25 +01:00
Tom Hvitved
46631d6eaf Merge pull request #10931 from hvitved/ruby/fix-flow-into-phis
Ruby: Fix flow steps into phi nodes
2022-11-02 21:07:06 +01:00
Chris Smowton
8e240a2e84 Kotlin: drop same-file requirement for overridden parameter labels 2022-11-02 19:28:53 +00:00
Chris Smowton
8eee450c65 Merge pull request #11064 from smowton/smowton/fix/kotlin-inherited-defaults
Kotlin: handle default parameter values inherited from an overridden function
2022-11-02 18:13:14 +00:00
Dave Bartolomeo
15be488c53 Fix typo 2022-11-02 12:40:55 -04:00
Dave Bartolomeo
a475e5758d Merge remote-tracking branch 'upstream/main' into dbartol/use-workspace-versions 2022-11-02 12:38:03 -04:00
Dave Bartolomeo
7cad4b7918 Revert changes to ATM, which isn't in the workspace 2022-11-02 12:37:30 -04:00
Chris Smowton
197be69425 Merge pull request #11069 from smowton/smowton/fix/kotlin-vararg-constructor-defaults
Kotlin vararg constructors: don't call a default-parameter constructor just because there are no varargs
2022-11-02 16:08:45 +00:00
Tamás Vajk
b59cb778ef Merge pull request #11077 from tamasvajk/kotlin-code-quality
Kotlin: Remove code duplication
2022-11-02 16:00:55 +01:00
Asger F
bac573bbed QL4QL: Add DependencyPath.ql query 2022-11-02 15:46:12 +01:00
Ian Lynagh
c2339b1203 Merge pull request #11050 from igfoo/igfoo/compiler_arguments
Kotlin: Run compiler_arguments test on all platforms
2022-11-02 14:07:36 +00:00
Ian Lynagh
285ff54853 Merge pull request #11052 from igfoo/igfoo/default-parameter-mad-flow
Kotlin: Run default-parameter-mad-flow on all platforms
2022-11-02 14:07:27 +00:00
Ian Lynagh
60fe5d6428 Merge pull request #11054 from igfoo/igfoo/gradle_kotlinx_serialization
Kotlin: Reunite the parts of gradle_kotlinx_serialization
2022-11-02 14:07:10 +00:00
Chris Smowton
cad268476c Accept test changes re: method source-locs 2022-11-02 14:00:14 +00:00
Chris Smowton
d704795d90 Use versioned all-overrides function 2022-11-02 13:57:53 +00:00
Chris Smowton
d700fddfdd Kotlin: handle default parameter values inherited from an overridden function 2022-11-02 13:57:53 +00:00
Paolo Tranquilli
2c517a3237 Swift: fix codegen test invocation 2022-11-02 14:48:20 +01:00
Paolo Tranquilli
99764450b3 Swift: remove redundant test run 2022-11-02 14:44:33 +01:00
Paolo Tranquilli
bc65d358f2 Swift: fix wrongly exchanged action bodies 2022-11-02 14:43:57 +01:00
Paolo Tranquilli
6ce6d9dc37 Swift: fix quick tests action, again 2022-11-02 14:42:14 +01:00
Paolo Tranquilli
08909e5c69 Swift: fix quick tests action 2022-11-02 14:38:07 +01:00
Paolo Tranquilli
17012c1a45 Swift: fix workflow job dependencies 2022-11-02 14:35:23 +01:00
Paolo Tranquilli
e6d4685109 Swift: split quick tests in separate action
Also, make the quick test list explicit in the action code, so we can
catch an inadvertant test deletion.
2022-11-02 14:32:45 +01:00
Jean Helie
37869e816b Merge pull request #11067 from github/jhelie/add-atm-model-integration-tests-hello-world
ATM: add hello world workflow for development of model integration te…
2022-11-02 14:20:51 +01:00
Tamas Vajk
1d3f4826a9 Fix failing internal checkß 2022-11-02 13:57:11 +01:00
Jean Helie
45320d91d1 Merge pull request #11065 from github/jhelie/add-check-to-run-atm-queries
ATM: add PR check running boosted queries
2022-11-02 12:28:40 +01:00
Chris Smowton
39520e54ea Restore enum class exclusion from constructor default parameters 2022-11-02 11:28:13 +00:00
Paolo Tranquilli
3acd4486a3 Swift: add tests for RUN_UNDER support
While I would have preferred to add a proper unit test, this required
more infrastructure for mocking system calls. Instead I made `qltest.sh`
accept a `//codeql-extractor-env` header and used that to write a QL
test exercising the `RUN_UNDER` functionality.
2022-11-02 12:09:13 +01:00
Tamas Vajk
145e2093f3 Kotlin: Remove code duplication 2022-11-02 11:46:33 +01:00
Tom Hvitved
f603d96f48 Merge pull request #11074 from github/revert-10576-ssa/consistency-queries
Revert "SSA: Turn consistency predicates into `query` predicates"
2022-11-02 11:29:42 +01:00
Tom Hvitved
f3e7d8778c Merge pull request #11075 from hvitved/ruby/avoid-ssa-deprecated-predicates
Ruby: Avoid calls to deprecated SSA predicates
2022-11-02 11:29:22 +01:00
Tom Hvitved
fa762d9952 C#: Fix flow steps into phi nodes
- Add missing flow from post-update nodes into phi nodes.
- Prevent flow from reads into phi nodes when use-use flow is prohibited.
2022-11-02 10:21:50 +01:00
Tom Hvitved
5b5dd07d60 C#: Add data flow test that illustrates issue with flow into phi nodes 2022-11-02 10:20:56 +01:00
Jean Helie
c4b750002e Merge branch 'main' into jhelie/add-atm-model-integration-tests-hello-world 2022-11-02 10:09:56 +01:00
Jean Helie
e8549a413b rename workflow 2022-11-02 10:09:06 +01:00
Tom Hvitved
2d5b9c12a6 Ruby: Avoid calls to deprecated SSA predicates 2022-11-02 09:37:28 +01:00
Tony Torralba
759ffc4743 Merge pull request #11027 from atorralba/atorralba/swift/webview-js-native-bridge-sources
Swift: WebView JS-native bridge sources
2022-11-02 09:32:57 +01:00
Tamás Vajk
79aba19dde Merge pull request #10951 from tamasvajk/kotlin-fix-startoffset
Kotlin: Fix location (start position) of method calls
2022-11-02 09:20:32 +01:00
Tom Hvitved
780ea72b3b Revert "SSA: Turn consistency predicates into query predicates" 2022-11-02 09:11:45 +01:00
Paolo Tranquilli
82998ce3a3 Merge branch 'main' into redsun82/swift-filtered-debugging 2022-11-02 06:39:16 +01:00
Paolo Tranquilli
57a616262f Swift: fix run cwd 2022-11-02 06:27:09 +01:00
Paolo Tranquilli
0d9ecfc4de Swift: move small bazel tests to build action 2022-11-02 06:23:44 +01:00
Paolo Tranquilli
6e370beb92 Swift: turn on macOS QL tests with slicing 2022-11-02 06:07:55 +01:00
Tom Hvitved
28b7ab7fbe Merge pull request #11066 from hvitved/ssa/deprecate-no-uncertain-reads-predicates 2022-11-01 22:06:08 +01:00
Jean Helie
3d1f75221b address @henrymercer's comments 2022-11-01 20:57:58 +01:00
Jean Helie
44bf8184fe ATM: add PR check running the boosted queries 2022-11-01 20:57:58 +01:00
Jean Helie
ce1092c33d add test repo 2022-11-01 20:57:58 +01:00
Chris Smowton
4910bf12e9 Kotlin vararg constructors: don't call a default-parameter constructor just because there are no varargs
This is the constructor case of https://github.com/github/codeql/pull/10909
2022-11-01 19:28:56 +00:00
Dave Bartolomeo
9d5e5e3ee7 ${workspace} all the things 2022-11-01 13:29:05 -04:00
Dave Bartolomeo
49c4c554c4 Merge from main 2022-11-01 13:22:40 -04:00
Tom Hvitved
ee9163aa40 Ruby: Fix flow steps into phi nodes
- Add missing flow from post-update nodes into phi nodes.
- Prevent flow from reads into phi nodes when use-use flow is prohibited.
2022-11-01 16:33:06 +01:00
Tom Hvitved
a191edfbd5 Ruby: Add data flow tests that illustrate problems with flow into SSA phi nodes 2022-11-01 16:32:46 +01:00
Tom Hvitved
640b0ce093 SSA: Deprecate *NoUncertainReads predicates 2022-11-01 15:21:32 +01:00
Jean Helie
1d6db8db9a ATM: add hello world workflow for development of model integration tests workflow 2022-11-01 14:51:11 +01:00
erik-krogh
6f3ca40fed expand the explanation to include with arguments make the commands vulnerable 2022-11-01 14:24:23 +01:00
Tom Hvitved
e8f9429b92 Merge pull request #10917 from hvitved/ruby/singleton-call-sensitivity
Ruby: Call-context sensitivity for singleton method calls
2022-11-01 14:13:26 +01:00
Erik Krogh Kristensen
8fd6424db9 fix the qhelp
Co-authored-by: Asger F <asgerf@github.com>
2022-11-01 14:05:25 +01:00
Geoffrey White
84c754e007 Merge pull request #11062 from geoffw0/rename
Swift: Rename ECB-Encryption directory
2022-11-01 12:59:53 +00:00
Arthur Baars
aba87a139d Merge pull request #10668 from aibaars/ruby-deps
Ruby: update dependencies
2022-11-01 13:55:42 +01:00
Tom Hvitved
f623ea0a55 Merge pull request #10576 from hvitved/ssa/consistency-queries
SSA: Turn consistency predicates into `query` predicates
2022-11-01 13:07:33 +01:00
Arthur Baars
8b39059d3a Update .github/workflows/ruby-build.yml 2022-11-01 10:49:12 +01:00
Geoffrey White
a1edd65542 Merge pull request #11034 from geoffw0/global
Swift: Add and use AbstractFunctionDecl.hasGlobalName predicate.
2022-11-01 09:27:26 +00:00
Geoffrey White
c3577b2256 Swift: Rename test directory. 2022-11-01 09:21:50 +00:00
Geoffrey White
7d80c5c7f7 Swift: Rename query directory. 2022-11-01 09:21:10 +00:00
Tom Hvitved
4edef874d6 SSA: Turn consistency predicates into query predicates 2022-11-01 10:01:56 +01:00
erik-krogh
84a7fddd95 remove explicit versions in lock files, as the dependencies are all installed locally 2022-11-01 09:09:26 +01:00
Erik Krogh Kristensen
ff2a5e8c27 Merge pull request #10986 from erik-krogh/tsPerf
JS: push more context into load/store steps from the exploratory flow-analysis
2022-11-01 09:03:24 +01:00
erik-krogh
5e5160d4fc add which commands are flagged in the change-note 2022-10-31 21:42:59 +01:00
Erik Krogh Kristensen
994c033c62 Merge pull request #11049 from erik-krogh/noCrossTalk
QL: prevent some cross-talk between modules
2022-10-31 21:41:00 +01:00
Tamas Vajk
91972d1d1f Kotlin: Fix location (start position) of method calls 2022-10-31 21:08:15 +01:00
Jeroen Ketema
222c9a6357 Merge pull request #11048 from jketema/add-constant-test
C++: Add `strcpy` test for `cpp/non-constant-format`
2022-10-31 18:01:13 +01:00
Ian Lynagh
caa56c9cad Kotlin: compiler_arguments test: Normalise path separators in output
Otherwise we get different output on Windows vs Posix.
2022-10-31 16:31:08 +00:00
Paolo Tranquilli
59284739dd Swift: reenable ql tests on macos 2022-10-31 17:07:56 +01:00
Jeroen Ketema
b43cbf7f95 Update cpp/ql/test/query-tests/Likely Bugs/Format/NonConstantFormat/test.cpp
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2022-10-31 17:03:29 +01:00
Paolo Tranquilli
80ea2b8c5e Swift: use macos-12-xl runners 2022-10-31 16:59:11 +01:00
Paolo Tranquilli
003866621f Swift: rework workflows
* A unique workflow file has been created merging all `swift-*.yml`
  workflows
* Change filtering at job level was added using [dorny/paths-filter][1]
* only one build of the extractor is made, and then shared via cache
  (not as an artifact because of [this longstading issue][2])
* integration tests are now run on on macOS
* qltests are not run any more on macOS to cut on feedback time
* autobuilder tests were moved to the macOS build step to avoid loading
  bazel twice

[1]: https://github.com/dorny/paths-filter#examples
[2]: https://github.com/actions/upload-artifact/issues/38
2022-10-31 16:59:11 +01:00
Ian Lynagh
067704a59a Kotlin: default-parameter-mad-flow test: Make kotlinc call work on Windows 2022-10-31 15:57:34 +00:00
Ian Lynagh
2783668092 Kotlin: compiler_arguments test: Fix running gradle on Windows 2022-10-31 15:29:23 +00:00
erik-krogh
86e81f523c add explicit this 2022-10-31 15:56:01 +01:00
Ian Lynagh
6b5deee9a8 Kotlin: Reunite the parts of gradle_kotlinx_serialization 2022-10-31 14:55:58 +00:00
Ian Lynagh
7c4df8c81f Kotlin: Run default-parameter-mad-flow on all platforms 2022-10-31 14:51:15 +00:00
erik-krogh
7d0beeafad QL: prevent some cross-talk between modules 2022-10-31 15:51:05 +01:00
Ian Lynagh
b1d9f9f9d5 Kotlin: Run compiler_arguments test on all platforms 2022-10-31 14:46:46 +00:00
Jeroen Ketema
abe9258943 C++: Add strcpy test for cpp/non-constant-format 2022-10-31 15:29:17 +01:00
Jeroen Ketema
83afc2a0ad C++: Add strcpy prototype to test 2022-10-31 15:25:35 +01:00
Ian Lynagh
21600c612d Merge pull request #11037 from igfoo/igfoo/log
Kotlin: Integration tests: Allow \ as a path separator in logs test
2022-10-31 14:03:57 +00:00
Tamás Vajk
e356720c73 Merge pull request #11014 from tamasvajk/kotlin-for-loop-var
Kotlin: Resugar `for` loops
2022-10-31 14:48:21 +01:00
Chris Smowton
d959630991 Merge pull request #11040 from smowton/smowton/fix/inherited-method-implementing-collection-interface
Kotlin: fix method types when an inherited method implements a collection type
2022-10-31 12:40:28 +00:00
Ian Lynagh
a53c2104d1 Kotlin: Integration tests: Allow \ as a path separator in logs test 2022-10-31 11:24:39 +00:00
Tony Torralba
b62ede1544 Fix issue in JsExportedSource
Model the source as an access to the tainted field, instead of the field itself (which didn't work)
2022-10-31 12:08:03 +01:00
Chris Smowton
c11d63e4d2 Merge pull request #11015 from smowton/smowton/fix/go-cleartext-logging-exclude-protobuf-getters
Go: exclude protobuf read steps from cleartext-logging query
2022-10-31 10:43:52 +00:00
Geoffrey White
ca586b4f3d Merge remote-tracking branch 'upstream/main' into global 2022-10-31 10:28:29 +00:00
Geoffrey White
0dd8f574a7 Swift: Redesign as a FreeFunctionDecl class + add some qldoc. 2022-10-31 10:24:12 +00:00
Geoffrey White
c161bb5e95 Merge pull request #11035 from geoffw0/simplify2
Swift: Simplify some more QL
2022-10-31 09:50:55 +00:00
Rasmus Wriedt Larsen
ead0844174 Merge pull request #10998 from RasmusWL/essa-use-use-test
Python: Add failing ESSA use-use test
2022-10-31 10:38:26 +01:00
Paolo Tranquilli
2b395985e6 Swift: remove unneeded trailing / in README.md 2022-10-31 09:55:03 +01:00
Paolo Tranquilli
e62acb1e8c Swift: revert wrong paragraph edit in README.md 2022-10-31 09:54:15 +01:00
Paolo Tranquilli
7237362feb Swift: add debug path mapping to README.md
This allows breakpoints to work more reliably, including on a bazel
project in CLion.
2022-10-31 09:51:41 +01:00
Paolo Tranquilli
46c7ee0e4f Swift: refactor RUN_UNDER code 2022-10-31 09:51:20 +01:00
Paolo Tranquilli
80debe19e0 Swift: fix RUN_UNDER_FILTER check 2022-10-31 09:50:45 +01:00
Tamas Vajk
4cd0f1ca66 Apply code review findings 2022-10-31 08:43:53 +01:00
Harry Maclean
3f403f0f87 Merge pull request #10700 from hmac/activesupport
Ruby: Model some ActiveSupport methods
2022-10-31 11:50:44 +13:00
erik-krogh
fc2112831c add second-order-command-injection query 2022-10-30 21:20:47 +01:00
Chris Smowton
b370497f96 Avoid split overrides 2022-10-29 18:23:45 +01:00
Chris Smowton
3573e211cc Correct test expectations 2022-10-29 11:40:58 +01:00
Chris Smowton
b6e4f472d1 Remove unnecessary import 2022-10-29 11:40:57 +01:00
Chris Smowton
6d321e0151 Add change note 2022-10-29 11:40:57 +01:00
Chris Smowton
5c66d87ed6 gofmt 2022-10-29 11:40:57 +01:00
Chris Smowton
0c6c135967 Go: exclude protobuf read steps from cleartext-logging query
This query already treats structs differently to usual: it includes field -> whole struct taint steps, but explicitly excludes struct -> field steps. This means that a logging framework sinking an entire struct with a tainted field yields an alert, but we don't get FPs caused by writing field `x` but then reading field `y`.

However, protobuf messages have a special treatment, with taint usually associated with the whole struct and getter methods propagating that taint out. Suppressing these getter method steps specifically for the cleartext-logging query mirrors its treatment of structs in general and avoids this sort of field-mismatch FP.

On the downside we will miss same-field propagation like `m.field = password; Log(m.GetField())` if we don't have source code for the implementation of `m`. However this is hopefully unusual since the typical use of protobufs is to serialize and deserialize, rather than using the struct as a general-purpose datastructure.
2022-10-29 11:40:57 +01:00
Chris Smowton
8266a22332 Kotlin: fix method types when an inherited method implements a collection type
In this circumstance the compiler seems to generate a specialised version of the implementing function with its argument type replaced by the interface-implementing child class' type parameter. However it stores a back-pointer to the real declared function, which we should use as the call target.
2022-10-29 11:29:04 +01:00
Dave Bartolomeo
85790fcade Merge pull request #10964 from smowton/smowton/admin/modernise-qlpacks
qlpacks: libraryPathDependencies -> dependencies
2022-10-28 16:44:22 -04:00
Chris Smowton
d9744c81b7 Merge pull request #11017 from smowton/smowton/fix/kotlin-wildcard-suppression-annotation
Kotlin: fix wildcard suppression where the annotation applies to a parent type/argument.
2022-10-28 18:33:07 +01:00
Ian Lynagh
84427e132e Kotlin: Move the logs test to all-platforms 2022-10-28 17:56:41 +01:00
Geoffrey White
f122005aaf Swift: Simplify out some variables. 2022-10-28 17:26:17 +01:00
Tony Torralba
2402504a4c Add missing SummaryPostUpdateNode 2022-10-28 18:24:17 +02:00
Geoffrey White
b4d939a620 Swift: Correct a comment. 2022-10-28 17:11:24 +01:00
Chris Smowton
1914a114a2 Merge pull request #11018 from smowton/smowton/fix/kotlin-extension-specialisation
Kotlin: specialise extension receivers the same as other function parameters
2022-10-28 16:15:41 +01:00
Chris Smowton
d6e2f5f4a8 Use ?.not() to negate a nullable boolean 2022-10-28 16:13:55 +01:00
Chris Smowton
1e1c9f639c Avoid Kotlin 1.5+ function firstNotNullOfOrNull 2022-10-28 16:13:55 +01:00
Chris Smowton
24f87ac963 Kotlin: fix wildcard suppression where the annotation applies to a parent type/argument.
In the process I also fix the missed case where suppression can be switched off using a parameterized annotation.
2022-10-28 16:13:55 +01:00
Ian Lynagh
2796d60d79 Merge pull request #11019 from igfoo/igfoo/win_integ
Kotlin: Get some integration tests running on Windows
2022-10-28 16:12:15 +01:00
Geoffrey White
648c2d09f9 Swift: Simplify InsecureTLS.ql. 2022-10-28 15:56:03 +01:00
Tony Torralba
baf7986cfa Rework types exported through JSContext
Better model the JSExport protocol logic
2022-10-28 15:56:05 +02:00
Rasmus Wriedt Larsen
a04c78ab94 Python: Apply suggestions from code review
Co-authored-by: yoff <lerchedahl@gmail.com>
2022-10-28 15:31:42 +02:00
Ian Lynagh
49425e6c2a Kotlin: Integration tests: Make a couple more posix-only for now 2022-10-28 13:59:36 +01:00
Geoffrey White
cf9c3afc86 Swift: Add and use AbstractFunctionDecl.hasGlobalName predicate. 2022-10-28 13:57:24 +01:00
Tamas Vajk
d745381ebe Remove unneeded consistency test output 2022-10-28 14:56:25 +02:00
Tamas Vajk
803a97df7f Kotlin: Resugar for loops with tuples as loop variables 2022-10-28 14:55:50 +02:00
Tamas Vajk
841340b266 Kotlin: Resugar for loops 2022-10-28 14:55:50 +02:00
Tamas Vajk
1e3060598f Kotlin: Add for loop tests 2022-10-28 14:55:50 +02:00
Paolo Tranquilli
3dcdc739de Swift: add possibility to run the extractor under an env-specified tool
if `CODEQL_EXTRACTOR_SWIFT_RUN_UNDER` env variable is set, and either
* `CODEQL_EXTRACTOR_SWIFT_RUN_UNDER_FILTER` is not set, or
* it is set to a regexp matching any substring of the extractor call
then the extractor process is substituted with the command (and possibly
options) stated in `CODEQL_EXTRACTOR_SWIFT_RUN_UNDER`, followed by the
system arguments of the extractor itself (which should include the
extractor program itself at the start).

Before calling `exec`, `CODEQL_EXTRACTOR_SWIFT_RUN_UNDER` is unset to
avoid unpleasant loops.

An example usage is to run the extractor under `gdbserver :1234` when
the arguments match a given source file.
2022-10-28 14:12:27 +02:00
Chris Smowton
366410ee9e Fix incorrect parameter ordering 2022-10-28 12:58:23 +01:00
Tony Torralba
48b0cc0229 Add models for JSContext and JSValue 2022-10-28 13:01:25 +02:00
Tony Torralba
81701547b2 Add taint sources for WKScriptMessage
This is what contains externally-provided data in Webview JS-native bridges
2022-10-28 12:58:27 +02:00
Ian Lynagh
f387eb21eb Kotlin: Integration tests: Add a qlpack.yml 2022-10-28 10:53:45 +01:00
Ian Lynagh
382c08e3cd Kotlin: Fix some integrations tests on Windows 2022-10-28 10:53:45 +01:00
Ian Lynagh
15d5369bdd Kotlin: Run some integration tests on Windows too 2022-10-28 10:53:45 +01:00
erik-krogh
0a7e797090 update expected outputs after reordering tests 2022-10-28 10:16:21 +02:00
erik-krogh
946720f414 reorder the CWE-078 tests into subdirectories 2022-10-28 10:16:21 +02:00
Harry Maclean
368ce69198 Fix qldoc formatting 2022-10-28 11:31:55 +13:00
Harry Maclean
9df8edcb1c Ruby: fix formatting 2022-10-28 11:31:55 +13:00
Harry Maclean
cd34686967 Ruby: Document flow summary for Hash#extract! 2022-10-28 11:31:55 +13:00
Harry Maclean
ca7b48c3d5 Add change note 2022-10-28 11:31:55 +13:00
Harry Maclean
5e781f24b6 Ruby: Remove duplicate test
This is already tested in hash-flow.
2022-10-28 11:31:55 +13:00
Harry Maclean
4ec527a9ea Ruby: Explain difference between flow tests
The type-tracking flow tests document the difference in sensitivity
between type-tracking and dataflow, so failures in that test are
expected.
2022-10-28 11:31:55 +13:00
Harry Maclean
6e8446b6ae Fix tests 2022-10-28 11:31:55 +13:00
Harry Maclean
ef260db76e Fix singleton set literal 2022-10-28 11:31:55 +13:00
Harry Maclean
71d703f2a5 Ruby: Add ActiveSupport extensions 2022-10-28 11:31:55 +13:00
Harry Maclean
cb37a0e835 Ruby: Add summaries for Hash#deep_merge(!) 2022-10-28 11:31:55 +13:00
Harry Maclean
3dea1d6a60 Ruby: Add flow summary for Hash#except! 2022-10-28 11:31:55 +13:00
Harry Maclean
0454642220 Ruby: Model deep_dup and presence 2022-10-28 11:31:55 +13:00
Harry Maclean
9f260853ac Ruby: Model more ActiveSupport string extensions 2022-10-28 11:31:55 +13:00
Harry Maclean
b389d50943 Ruby: Identify safe_constantize 2022-10-28 11:31:54 +13:00
Chris Smowton
45a4cd89a6 Kotlin: specialise extension receivers the same as other function parameters
This arises when a generic class extends one of its parameters; for example, `class G<T> { val T.v; get() = 1 }`, where specialisation `G<List>` should generate a method specialisation `getV(List)`.
2022-10-27 18:31:19 +01:00
Dave Bartolomeo
23b572e9b7 Use ${workspace} for intra-workspace dependencies
Now that the released CLI supports replacement variables in dependency version ranges, we can now mark our published library packs as depending on whatever version of their dependency is in our workspace, without having to manually bump the dependency version every release.

Note that when the packs are published, the dependencies in the published pack file are rewritten to have the correct specific version.
2022-10-26 16:40:01 -04:00
Rasmus Wriedt Larsen
b3f29b0a53 Python: Add failing ESSA use-use test
I initially created this as a dataflow test, but then realized it could
just be an ESSA test. I cound't find any existing ESSA tests though :|
so created a new dir for it.
2022-10-26 17:49:33 +02:00
erik-krogh
21e7e27e1f push more context into load/store steps from the exploratory flow-analysis 2022-10-26 10:52:47 +02:00
Tom Hvitved
4422327c00 Ruby: Call-context sensitivity for singleton method calls 2022-10-21 11:48:25 +02:00
Tom Hvitved
6feff7e3ed Ruby: Add more data-flow call sensitivity tests 2022-10-21 09:36:34 +02:00
Anders Schack-Mulligen
9ebcaf80e7 Java: Fix some join-orders. 2022-10-20 14:23:36 +02:00
Arthur Baars
ae7e6ef701 Ruby: update dependencies 2022-10-04 13:44:22 +02:00
588 changed files with 12912 additions and 6821 deletions

View File

@@ -1,14 +1,22 @@
name: Fetch CodeQL
description: Fetches the latest version of CodeQL
inputs:
channel:
description: 'The CodeQL channel to use'
required: false
default: 'nightly'
runs:
using: composite
steps:
- name: Fetch CodeQL
shell: bash
run: |
gh extension install github/gh-codeql
gh codeql set-channel nightly
gh codeql version
gh codeql version --format=json | jq -r .unpackedLocation >> "${GITHUB_PATH}"
env:
GITHUB_TOKEN: ${{ github.token }}
CHANNEL: ${{ inputs.channel }}
run: |
gh extension install github/gh-codeql
gh codeql set-channel "$CHANNEL"
gh codeql version
gh codeql version --format=json | jq -r .unpackedLocation >> "${GITHUB_PATH}"

3
.github/labeler.yml vendored
View File

@@ -51,3 +51,6 @@ documentation:
- "java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll"
- "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll"
- "java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll"
"ATM":
- javascript/ql/experimental/adaptivethreatmodeling/**/*

View File

@@ -1,13 +1,56 @@
name: ATM Check Queries Run
# This check is required, therefore we must run it on all PRs, even if only Markdown has changed.
env:
DB_PATH: test_db
ATM_MODEL_PACK: javascript/ql/experimental/adaptivethreatmodeling/src
QUERY_SUITE: codeql-suites/javascript-atm-code-scanning.qls
on:
pull_request:
paths:
- ".github/workflows/atm-check-queries-run.yml"
- "javascript/ql/experimental/adaptivethreatmodeling/**"
workflow_dispatch:
jobs:
hello-world:
run-atm-queries:
runs-on: ubuntu-latest
steps:
- name: foo
run: echo "Hello world"
- uses: actions/checkout@v3
- name: Install CodeQL CLI
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh extensions install github/gh-codeql
gh codeql download
- name: Install ATM model pack
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -exu
# Install ATM model pack
gh codeql pack install ${ATM_MODEL_PACK}
# Retrieve model checksum
model_checksum=$(gh codeql resolve extensions ${ATM_MODEL_PACK}/${QUERY_SUITE} | jq -r '.models[0].checksum')
# Trust the model so that we can use it in the ATM boosted queries
mkdir -p "$HOME/.config/codeql"
echo "--insecurely-execute-ml-model-checksums ${model_checksum}" >> "$HOME/.config/codeql/config"
- name: Create test DB
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh codeql database create ${RUNNER_TEMP}/${DB_PATH} --source-root config/atm/ --language javascript
- name: Run ATM query suite
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh codeql database run-queries -vv -- ${RUNNER_TEMP}/${DB_PATH} ${ATM_MODEL_PACK}/${QUERY_SUITE}

View File

@@ -0,0 +1,12 @@
name: ATM Model Integration Tests
on:
workflow_dispatch:
jobs:
hello-world:
runs-on: ubuntu-latest
steps:
- name: foo
run: echo "Hello world"

57
.github/workflows/compile-queries.yml vendored Normal file
View File

@@ -0,0 +1,57 @@
name: "Compile all queries using the latest stable CodeQL CLI"
on:
push:
branches: [main] # makes sure the cache gets populated
pull_request:
branches:
- main
- "rc/*"
jobs:
compile-queries:
runs-on: ubuntu-latest-xl
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
# calculate the merge-base with main, in a way that works both on PRs and pushes to main.
- name: Calculate merge-base
if: ${{ github.event_name == 'pull_request' }}
env:
BASE_BRANCH: ${{ github.base_ref }}
run: |
MERGE_BASE=$(git merge-base --fork-point origin/$BASE_BRANCH)
echo "merge-base=$MERGE_BASE" >> $GITHUB_ENV
- name: Calculate merge-base - branch
if: ${{ github.event_name != 'pull_request' }}
# using github.sha instead, since we're directly on a branch, and not in a PR
run: |
MERGE_BASE=${{ github.sha }}
echo "merge-base=$MERGE_BASE" >> $GITHUB_ENV
- name: Cache CodeQL query compilation
uses: actions/cache@v3
with:
path: '*/ql/src/.cache'
# current GH HEAD first, merge-base second, generic third
key: codeql-stable-compile-${{ github.sha }}
restore-keys: |
codeql-stable-compile-${{ env.merge-base }}
codeql-stable-compile-
- name: Setup CodeQL
uses: ./.github/actions/fetch-codeql
with:
channel: 'release'
- name: check formatting
run: codeql query format */ql/{src,lib,test}/**/*.{qll,ql} --check-only
- name: compile queries - check-only
# run with --check-only if running in a PR (github.sha != main)
if : ${{ github.event_name == 'pull_request' }}
shell: bash
run: codeql query compile -j0 */ql/src --keep-going --warnings=error --check-only
- name: compile queries - full
# do full compile if running on main - this populates the cache
if : ${{ github.event_name != 'pull_request' }}
shell: bash
run: codeql query compile -j0 */ql/src --keep-going --warnings=error

View File

@@ -96,8 +96,8 @@ jobs:
- name: Build Query Pack
run: |
codeql pack create ../shared/ssa --output target/packs
codeql pack create ../misc/suite-helpers --output target/packs
codeql pack create ql/lib --output target/packs
codeql pack install ql/src
codeql pack create ql/src --output target/packs
PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*)
codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src
@@ -202,7 +202,7 @@ jobs:
echo 'name: sample-tests
version: 0.0.0
dependencies:
codeql/ruby-all: 0.0.1
codeql/ruby-all: "*"
extractor: ruby
tests: .
' > qlpack.yml

View File

@@ -1,27 +0,0 @@
name: "Swift: Build and test Xcode autobuilder"
on:
pull_request:
paths:
- "swift/xcode-autobuilder/**"
- "misc/bazel/**"
- "*.bazel*"
- .github/workflows/swift-autobuilder.yml
branches:
- main
jobs:
autobuilder:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- uses: bazelbuild/setup-bazelisk@v2
- uses: actions/setup-python@v4
with:
python-version-file: 'swift/.python-version'
- name: Build the Xcode autobuilder
run: |
bazel build //swift/xcode-autobuilder
- name: Test the Xcode autobuilder
run: |
bazel test //swift/xcode-autobuilder/tests

View File

@@ -1,44 +0,0 @@
name: "Swift: Check code generation"
on:
pull_request:
paths:
- "swift/**"
- "misc/bazel/**"
- "*.bazel*"
- .github/workflows/swift-codegen.yml
- .github/actions/fetch-codeql/action.yml
branches:
- main
defaults:
run:
working-directory: swift
jobs:
codegen:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/fetch-codeql
- uses: bazelbuild/setup-bazelisk@v2
- uses: actions/setup-python@v4
with:
python-version-file: 'swift/.python-version'
- uses: pre-commit/action@v3.0.0
name: Check that python code is properly formatted
with:
extra_args: autopep8 --all-files
- name: Run unit tests
run: |
bazel test //swift/codegen/test --test_output=errors
- uses: pre-commit/action@v3.0.0
name: Check that QL generated code was checked in
with:
extra_args: swift-codegen --all-files
- name: Generate C++ files
run: |
bazel run //swift/codegen:codegen -- --generate=trap,cpp --cpp-output=$PWD/swift-generated-cpp-files
- uses: actions/upload-artifact@v3
with:
name: swift-generated-cpp-files
path: swift-generated-cpp-files/**

View File

@@ -1,47 +0,0 @@
name: "Swift: Run Integration Tests"
on:
pull_request:
paths:
- "swift/**"
- "misc/bazel/**"
- "*.bazel*"
- .github/workflows/swift-integration-tests.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
branches:
- main
defaults:
run:
working-directory: swift
jobs:
integration-tests:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-20.04
# - macos-latest TODO
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/fetch-codeql
- uses: bazelbuild/setup-bazelisk@v2
- uses: actions/setup-python@v4
with:
python-version-file: 'swift/.python-version'
- name: Build Swift extractor
run: |
bazel run //swift:create-extractor-pack
- name: Get Swift version
id: get_swift_version
run: |
VERSION=$(bazel run //swift/extractor -- --version | sed -ne 's/.*version \(\S*\).*/\1/p')
echo "::set-output name=version::$VERSION"
- uses: swift-actions/setup-swift@v1
with:
swift-version: "${{steps.get_swift_version.outputs.version}}"
- name: Run integration tests
run: |
python integration-tests/runner.py

View File

@@ -1,57 +0,0 @@
name: "Swift: Run QL Tests"
on:
pull_request:
paths:
- "swift/**"
- "misc/bazel/**"
- "*.bazel*"
- .github/workflows/swift-qltest.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
branches:
- main
defaults:
run:
working-directory: swift
jobs:
qlformat:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/fetch-codeql
- name: Check QL formatting
run: find ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 codeql query format --check-only
qltest-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: bazelbuild/setup-bazelisk@v2
- uses: actions/setup-python@v4
with:
python-version-file: 'swift/.python-version'
- name: Test qltest.sh
run: |
bazel test //swift/tools/test/qltest
qltest:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-20.04, macos-latest ]
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/fetch-codeql
- uses: bazelbuild/setup-bazelisk@v2
- uses: actions/setup-python@v4
with:
python-version-file: 'swift/.python-version'
- name: Build Swift extractor
run: |
bazel run //swift:create-extractor-pack
- name: Run QL tests
run: |
codeql test run --threads=0 --ram 5000 --search-path "${{ github.workspace }}/swift/extractor-pack" --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition ql/test
env:
GITHUB_TOKEN: ${{ github.token }}

121
.github/workflows/swift.yml vendored Normal file
View File

@@ -0,0 +1,121 @@
name: "Swift"
on:
pull_request:
paths:
- "swift/**"
- "misc/bazel/**"
- "*.bazel*"
- .github/workflows/swift.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
- .pre-commit-config.yaml
- "!**/*.md"
- "!**/*.qhelp"
branches:
- main
jobs:
changes:
runs-on: ubuntu-latest
outputs:
codegen: ${{ steps.filter.outputs.codegen }}
ql: ${{ steps.filter.outputs.ql }}
steps:
- uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50
id: filter
with:
filters: |
codegen:
- 'github/workflows/swift.yml'
- "misc/bazel/**"
- "*.bazel*"
- 'swift/actions/setup-env/**'
- '.pre-commit-config.yaml'
- 'swift/codegen/**'
- 'swift/schema.py'
- 'swift/**/*.dbscheme'
- 'swift/ql/lib/codeql/swift/elements.qll'
- 'swift/ql/lib/codeql/swift/elements/**'
- 'swift/ql/lib/codeql/swift/generated/**'
- 'swift/ql/test/extractor-tests/generated/**'
ql:
- 'github/workflows/swift.yml'
- 'swift/**/*.ql'
- 'swift/**/*.qll'
# not using a matrix as you cannot depend on a specific job in a matrix, and we want to start linux checks
# without waiting for the macOS build
build-and-test-macos:
runs-on: macos-12-xl
steps:
- uses: actions/checkout@v3
- uses: ./swift/actions/create-extractor-pack
- uses: ./swift/actions/run-quick-tests
build-and-test-linux:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: ./swift/actions/create-extractor-pack
- uses: ./swift/actions/run-quick-tests
qltests-linux:
needs: build-and-test-linux
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./swift/actions/run-ql-tests
qltests-macos:
needs: build-and-test-macos
runs-on: macos-12-xl
strategy:
fail-fast: false
matrix:
slice: ["1/2", "2/2"]
steps:
- uses: actions/checkout@v3
- uses: ./swift/actions/run-ql-tests
with:
flags: --slice ${{ matrix.slice }}
integration-tests-linux:
needs: build-and-test-linux
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./swift/actions/run-integration-tests
integration-tests-macos:
needs: build-and-test-macos
runs-on: macos-12-xl
steps:
- uses: actions/checkout@v3
- uses: ./swift/actions/run-integration-tests
codegen:
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.codegen == 'true' }}
steps:
- uses: actions/checkout@v3
- uses: ./swift/actions/setup-env
- uses: pre-commit/action@v3.0.0
name: Check that python code is properly formatted
with:
extra_args: autopep8 --all-files
- uses: ./.github/actions/fetch-codeql
- uses: pre-commit/action@v3.0.0
name: Check that QL generated code was checked in
with:
extra_args: swift-codegen --all-files
- name: Generate C++ files
run: |
bazel run //swift/codegen:codegen -- --generate=trap,cpp --cpp-output=$PWD/generated-cpp-files
- uses: actions/upload-artifact@v3
with:
name: swift-generated-cpp-files
path: swift/generated-cpp-files/**
qlformat:
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.ql == 'true' }}
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/fetch-codeql
- name: Check QL formatting
run: find swift/ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 codeql query format --check-only

View File

@@ -17,6 +17,7 @@ provide:
# - "javascript/ql/experimental/adaptivethreatmodeling/model/qlpack.yml"
- "javascript/ql/experimental/adaptivethreatmodeling/modelbuilding/qlpack.yml"
- "javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml"
- "javascript/ql/experimental/adaptivethreatmodeling/test/qlpack.yml"
- "csharp/ql/campaigns/Solorigate/lib/qlpack.yml"
- "csharp/ql/campaigns/Solorigate/src/qlpack.yml"
- "csharp/ql/campaigns/Solorigate/test/qlpack.yml"

View File

@@ -0,0 +1,21 @@
const mongoose = require('mongoose');
Logger = require('./logger').Logger;
Note = require('./models/note').Note;
(async () => {
if (process.argv.length != 5) {
Logger.log("Creates a private note. Usage: node add-note.js <token> <title> <body>")
return;
}
// Open the default mongoose connection
await mongoose.connect('mongodb://localhost:27017/notes', { useFindAndModify: false });
const [userToken, title, body] = process.argv.slice(2);
await Note.create({ title, body, userToken });
Logger.log(`Created private note with title ${title} and body ${body} belonging to user with token ${userToken}.`);
await mongoose.connection.close();
})();

View File

@@ -0,0 +1,68 @@
const bodyParser = require('body-parser');
const express = require('express');
const mongoose = require('mongoose');
const notesApi = require('./notes-api');
const usersApi = require('./users-api');
const addSampleData = module.exports.addSampleData = async () => {
const [userA, userB] = await User.create([
{
name: "A",
token: "tokenA"
},
{
name: "B",
token: "tokenB"
}
]);
await Note.create([
{
title: "Public note belonging to A",
body: "This is a public note belonging to A",
isPublic: true,
ownerToken: userA.token
},
{
title: "Public note belonging to B",
body: "This is a public note belonging to B",
isPublic: true,
ownerToken: userB.token
},
{
title: "Private note belonging to A",
body: "This is a private note belonging to A",
ownerToken: userA.token
},
{
title: "Private note belonging to B",
body: "This is a private note belonging to B",
ownerToken: userB.token
}
]);
}
module.exports.startApp = async () => {
// Open the default mongoose connection
await mongoose.connect('mongodb://mongo:27017/notes', { useFindAndModify: false });
// Drop contents of DB
mongoose.connection.dropDatabase();
// Add some sample data
await addSampleData();
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.get('/', async (_req, res) => {
res.send('Hello World');
});
app.use('/api/notes', notesApi.router);
app.use('/api/users', usersApi.router);
app.listen(3000);
Logger.log('Express started on port 3000');
};

View File

@@ -0,0 +1,7 @@
const startApp = require('./app').startApp;
Logger = require('./logger').Logger;
Note = require('./models/note').Note;
User = require('./models/user').User;
startApp();

View File

@@ -0,0 +1,5 @@
module.exports.Logger = class {
log(message, ...objs) {
console.log(message, objs);
}
};

View File

@@ -0,0 +1,8 @@
const mongoose = require('mongoose');
module.exports.Note = mongoose.model('Note', new mongoose.Schema({
title: String,
body: String,
ownerToken: String,
isPublic: Boolean
}));

View File

@@ -0,0 +1,6 @@
const mongoose = require('mongoose');
module.exports.User = mongoose.model('User', new mongoose.Schema({
name: String,
token: String
}));

View File

@@ -0,0 +1,44 @@
const express = require('express')
const router = module.exports.router = express.Router();
function serializeNote(note) {
return {
title: note.title,
body: note.body
};
}
router.post('/find', async (req, res) => {
const notes = await Note.find({
ownerToken: req.body.token
}).exec();
res.json({
notes: notes.map(serializeNote)
});
});
router.get('/findPublic', async (_req, res) => {
const notes = await Note.find({
isPublic: true
}).exec();
res.json({
notes: notes.map(serializeNote)
});
});
router.post('/findVisible', async (req, res) => {
const notes = await Note.find({
$or: [
{
isPublic: true
},
{
ownerToken: req.body.token
}
]
}).exec();
res.json({
notes: notes.map(serializeNote)
});
});

View File

@@ -0,0 +1,37 @@
const mongoose = require('mongoose');
Logger = require('./logger').Logger;
Note = require('./models/note').Note;
User = require('./models/user').User;
(async () => {
if (process.argv.length != 3) {
Logger.log("Outputs all notes visible to a user. Usage: node read-notes.js <token>")
return;
}
// Open the default mongoose connection
await mongoose.connect('mongodb://localhost:27017/notes', { useFindAndModify: false });
const ownerToken = process.argv[2];
const user = await User.findOne({
token: ownerToken
}).exec();
const notes = await Note.find({
$or: [
{ isPublic: true },
{ ownerToken }
]
}).exec();
notes.map(note => {
Logger.log("Title:" + note.title);
Logger.log("By:" + user.name);
Logger.log("Body:" + note.body);
Logger.log();
});
await mongoose.connection.close();
})();

View File

@@ -0,0 +1,25 @@
const express = require('express')
Logger = require('./logger').Logger;
const router = module.exports.router = express.Router();
router.post('/updateName', async (req, res) => {
Logger.log("/updateName called with new name", req.body.name);
await User.findOneAndUpdate({
token: req.body.token
}, {
name: req.body.name
}).exec();
res.json({
name: req.body.name
});
});
router.post('/getName', async (req, res) => {
const user = await User.findOne({
token: req.body.token
}).exec();
res.json({
name: user.name
});
});

View File

@@ -3,4 +3,4 @@ groups:
- cpp
- examples
dependencies:
codeql/cpp-all: "*"
codeql/cpp-all: ${workspace}

View File

@@ -1,3 +1,9 @@
## 0.4.3
### Minor Analysis Improvements
* Fixed bugs in the `FormatLiteral` class that were causing `getMaxConvertedLength` and related predicates to return no results when the format literal was `%e`, `%f` or `%g` and an explicit precision was specified.
## 0.4.2
No user-facing changes.

View File

@@ -1,4 +1,5 @@
---
category: minorAnalysis
---
## 0.4.3
### Minor Analysis Improvements
* Fixed bugs in the `FormatLiteral` class that were causing `getMaxConvertedLength` and related predicates to return no results when the format literal was `%e`, `%f` or `%g` and an explicit precision was specified.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.2
lastReleaseVersion: 0.4.3

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -1,9 +1,9 @@
name: codeql/cpp-all
version: 0.4.3-dev
version: 0.4.3
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp
library: true
upgrades: upgrades
dependencies:
codeql/ssa: 0.0.1
codeql/ssa: ${workspace}

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -98,16 +98,16 @@ class ParameterPosition = Position;
/** An argument position represented by an integer. */
class ArgumentPosition = Position;
class Position extends TPosition {
abstract class Position extends TPosition {
abstract string toString();
}
class DirectPosition extends TDirectPosition {
class DirectPosition extends Position, TDirectPosition {
int index;
DirectPosition() { this = TDirectPosition(index) }
string toString() {
override string toString() {
index = -1 and
result = "this"
or
@@ -118,12 +118,12 @@ class DirectPosition extends TDirectPosition {
int getIndex() { result = index }
}
class IndirectionPosition extends TIndirectionPosition {
class IndirectionPosition extends Position, TIndirectionPosition {
int index;
IndirectionPosition() { this = TIndirectionPosition(index) }
string toString() {
override string toString() {
index = -1 and
result = "this"
or

View File

@@ -1,3 +1,9 @@
## 0.4.3
### Minor Analysis Improvements
* Fixed a bug in `cpp/jsf/av-rule-76` that caused the query to miss results when an implicitly-defined copy constructor or copy assignment operator was generated.
## 0.4.2
### New Queries

View File

@@ -0,0 +1,5 @@
## 0.4.3
### Minor Analysis Improvements
* Fixed a bug in `cpp/jsf/av-rule-76` that caused the query to miss results when an implicitly-defined copy constructor or copy assignment operator was generated.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.2
lastReleaseVersion: 0.4.3

View File

@@ -38,9 +38,9 @@ predicate hasNontrivialDestructor(Class c) {
from Class c
where
(hasPointerMember(c) or hasNontrivialDestructor(c)) and
not (
c.getAMemberFunction() instanceof CopyConstructor and
c.getAMemberFunction() instanceof CopyAssignmentOperator
(
c.hasImplicitCopyAssignmentOperator() or
c.hasImplicitCopyConstructor()
) and
not c instanceof Struct
select c,

View File

@@ -1,11 +1,11 @@
name: codeql/cpp-queries
version: 0.4.3-dev
version: 0.4.3
groups:
- cpp
- queries
dependencies:
codeql/cpp-all: "*"
codeql/suite-helpers: "*"
codeql/cpp-all: ${workspace}
codeql/suite-helpers: ${workspace}
suites: codeql-suites
extractor: cpp
defaultSuiteFile: codeql-suites/cpp-code-scanning.qls

View File

@@ -2,43 +2,21 @@ edges
| test.cpp:4:15:4:20 | call to malloc | test.cpp:5:15:5:15 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:5:15:5:22 | ... + ... |
| test.cpp:5:15:5:15 | Load | test.cpp:5:15:5:22 | ... + ... |
| test.cpp:5:15:5:15 | Load | test.cpp:5:15:5:22 | ... + ... |
| test.cpp:5:15:5:15 | Load | test.cpp:5:15:5:22 | ... + ... |
| test.cpp:5:15:5:15 | Load | test.cpp:5:15:5:22 | Store |
| test.cpp:5:15:5:15 | Load | test.cpp:5:15:5:22 | Store |
| test.cpp:5:15:5:15 | Load | test.cpp:5:15:5:22 | Store |
| test.cpp:5:15:5:15 | Load | test.cpp:5:15:5:22 | Store |
| test.cpp:5:15:5:15 | Load | test.cpp:6:15:6:15 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:6:15:6:15 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:6:15:6:15 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:6:15:6:15 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:7:16:7:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:7:16:7:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:7:16:7:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:7:16:7:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:8:16:8:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:8:16:8:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:8:16:8:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:8:16:8:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:8:16:8:20 | ... + ... |
| test.cpp:5:15:5:15 | Load | test.cpp:8:16:8:20 | ... + ... |
| test.cpp:5:15:5:15 | Load | test.cpp:8:16:8:20 | ... + ... |
| test.cpp:5:15:5:15 | Load | test.cpp:8:16:8:20 | ... + ... |
| test.cpp:5:15:5:15 | Load | test.cpp:9:16:9:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:9:16:9:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:9:16:9:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:9:16:9:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:10:16:10:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:10:16:10:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:10:16:10:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:10:16:10:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:11:16:11:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:11:16:11:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:11:16:11:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:11:16:11:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:12:16:12:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:12:16:12:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:12:16:12:16 | Load |
| test.cpp:5:15:5:15 | Load | test.cpp:12:16:12:16 | Load |
| test.cpp:5:15:5:22 | ... + ... | test.cpp:5:15:5:22 | Store |
| test.cpp:5:15:5:22 | ... + ... | test.cpp:5:15:5:22 | Store |
@@ -116,7 +94,6 @@ edges
| test.cpp:8:16:8:16 | Load | test.cpp:11:16:11:16 | Load |
| test.cpp:8:16:8:16 | Load | test.cpp:12:16:12:16 | Load |
| test.cpp:8:16:8:20 | ... + ... | test.cpp:8:14:8:21 | Load: * ... |
| test.cpp:8:16:8:20 | ... + ... | test.cpp:8:14:8:21 | Load: * ... |
| test.cpp:9:16:9:16 | Load | test.cpp:6:14:6:15 | Load: * ... |
| test.cpp:9:16:9:16 | Load | test.cpp:6:14:6:15 | Load: * ... |
| test.cpp:9:16:9:16 | Load | test.cpp:8:14:8:21 | Load: * ... |
@@ -139,62 +116,30 @@ edges
| test.cpp:11:16:11:16 | Load | test.cpp:8:14:8:21 | Load: * ... |
| test.cpp:11:16:11:16 | Load | test.cpp:12:16:12:16 | Load |
| test.cpp:12:16:12:16 | Load | test.cpp:6:14:6:15 | Load: * ... |
| test.cpp:12:16:12:16 | Load | test.cpp:6:14:6:15 | Load: * ... |
| test.cpp:12:16:12:16 | Load | test.cpp:8:14:8:21 | Load: * ... |
| test.cpp:12:16:12:16 | Load | test.cpp:8:14:8:21 | Load: * ... |
| test.cpp:16:15:16:20 | call to malloc | test.cpp:17:15:17:15 | Load |
| test.cpp:17:15:17:15 | Load | test.cpp:17:15:17:22 | ... + ... |
| test.cpp:17:15:17:15 | Load | test.cpp:17:15:17:22 | ... + ... |
| test.cpp:17:15:17:15 | Load | test.cpp:17:15:17:22 | ... + ... |
| test.cpp:17:15:17:15 | Load | test.cpp:17:15:17:22 | ... + ... |
| test.cpp:17:15:17:15 | Load | test.cpp:20:16:20:20 | ... + ... |
| test.cpp:17:15:17:15 | Load | test.cpp:20:16:20:20 | ... + ... |
| test.cpp:17:15:17:15 | Load | test.cpp:20:16:20:20 | ... + ... |
| test.cpp:17:15:17:15 | Load | test.cpp:20:16:20:20 | ... + ... |
| test.cpp:17:15:17:22 | ... + ... | test.cpp:20:14:20:21 | Load: * ... |
| test.cpp:17:15:17:22 | ... + ... | test.cpp:20:14:20:21 | Load: * ... |
| test.cpp:20:16:20:20 | ... + ... | test.cpp:20:14:20:21 | Load: * ... |
| test.cpp:20:16:20:20 | ... + ... | test.cpp:20:14:20:21 | Load: * ... |
| test.cpp:28:15:28:20 | call to malloc | test.cpp:29:15:29:15 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:29:15:29:28 | ... + ... |
| test.cpp:29:15:29:15 | Load | test.cpp:29:15:29:28 | ... + ... |
| test.cpp:29:15:29:15 | Load | test.cpp:29:15:29:28 | ... + ... |
| test.cpp:29:15:29:15 | Load | test.cpp:29:15:29:28 | ... + ... |
| test.cpp:29:15:29:15 | Load | test.cpp:29:15:29:28 | Store |
| test.cpp:29:15:29:15 | Load | test.cpp:29:15:29:28 | Store |
| test.cpp:29:15:29:15 | Load | test.cpp:29:15:29:28 | Store |
| test.cpp:29:15:29:15 | Load | test.cpp:29:15:29:28 | Store |
| test.cpp:29:15:29:15 | Load | test.cpp:30:15:30:15 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:30:15:30:15 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:30:15:30:15 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:30:15:30:15 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:31:16:31:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:31:16:31:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:31:16:31:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:31:16:31:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:32:16:32:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:32:16:32:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:32:16:32:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:32:16:32:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:32:16:32:20 | ... + ... |
| test.cpp:29:15:29:15 | Load | test.cpp:32:16:32:20 | ... + ... |
| test.cpp:29:15:29:15 | Load | test.cpp:32:16:32:20 | ... + ... |
| test.cpp:29:15:29:15 | Load | test.cpp:32:16:32:20 | ... + ... |
| test.cpp:29:15:29:15 | Load | test.cpp:33:16:33:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:33:16:33:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:33:16:33:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:33:16:33:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:34:16:34:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:34:16:34:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:34:16:34:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:34:16:34:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:35:16:35:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:35:16:35:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:35:16:35:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:35:16:35:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:36:16:36:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:36:16:36:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:36:16:36:16 | Load |
| test.cpp:29:15:29:15 | Load | test.cpp:36:16:36:16 | Load |
| test.cpp:29:15:29:28 | ... + ... | test.cpp:29:15:29:28 | Store |
| test.cpp:29:15:29:28 | ... + ... | test.cpp:29:15:29:28 | Store |
@@ -272,7 +217,6 @@ edges
| test.cpp:32:16:32:16 | Load | test.cpp:35:16:35:16 | Load |
| test.cpp:32:16:32:16 | Load | test.cpp:36:16:36:16 | Load |
| test.cpp:32:16:32:20 | ... + ... | test.cpp:32:14:32:21 | Load: * ... |
| test.cpp:32:16:32:20 | ... + ... | test.cpp:32:14:32:21 | Load: * ... |
| test.cpp:33:16:33:16 | Load | test.cpp:30:14:30:15 | Load: * ... |
| test.cpp:33:16:33:16 | Load | test.cpp:30:14:30:15 | Load: * ... |
| test.cpp:33:16:33:16 | Load | test.cpp:32:14:32:21 | Load: * ... |
@@ -295,49 +239,25 @@ edges
| test.cpp:35:16:35:16 | Load | test.cpp:32:14:32:21 | Load: * ... |
| test.cpp:35:16:35:16 | Load | test.cpp:36:16:36:16 | Load |
| test.cpp:36:16:36:16 | Load | test.cpp:30:14:30:15 | Load: * ... |
| test.cpp:36:16:36:16 | Load | test.cpp:30:14:30:15 | Load: * ... |
| test.cpp:36:16:36:16 | Load | test.cpp:32:14:32:21 | Load: * ... |
| test.cpp:36:16:36:16 | Load | test.cpp:32:14:32:21 | Load: * ... |
| test.cpp:40:15:40:20 | call to malloc | test.cpp:41:15:41:15 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:41:15:41:28 | ... + ... |
| test.cpp:41:15:41:15 | Load | test.cpp:41:15:41:28 | ... + ... |
| test.cpp:41:15:41:15 | Load | test.cpp:41:15:41:28 | ... + ... |
| test.cpp:41:15:41:15 | Load | test.cpp:41:15:41:28 | ... + ... |
| test.cpp:41:15:41:15 | Load | test.cpp:41:15:41:28 | Store |
| test.cpp:41:15:41:15 | Load | test.cpp:41:15:41:28 | Store |
| test.cpp:41:15:41:15 | Load | test.cpp:41:15:41:28 | Store |
| test.cpp:41:15:41:15 | Load | test.cpp:41:15:41:28 | Store |
| test.cpp:41:15:41:15 | Load | test.cpp:42:15:42:15 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:42:15:42:15 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:42:15:42:15 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:42:15:42:15 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:43:16:43:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:43:16:43:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:43:16:43:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:43:16:43:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:44:16:44:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:44:16:44:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:44:16:44:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:44:16:44:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:44:16:44:20 | ... + ... |
| test.cpp:41:15:41:15 | Load | test.cpp:44:16:44:20 | ... + ... |
| test.cpp:41:15:41:15 | Load | test.cpp:44:16:44:20 | ... + ... |
| test.cpp:41:15:41:15 | Load | test.cpp:44:16:44:20 | ... + ... |
| test.cpp:41:15:41:15 | Load | test.cpp:45:16:45:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:45:16:45:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:45:16:45:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:45:16:45:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:46:16:46:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:46:16:46:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:46:16:46:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:46:16:46:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:47:16:47:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:47:16:47:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:47:16:47:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:47:16:47:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:48:16:48:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:48:16:48:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:48:16:48:16 | Load |
| test.cpp:41:15:41:15 | Load | test.cpp:48:16:48:16 | Load |
| test.cpp:41:15:41:28 | ... + ... | test.cpp:41:15:41:28 | Store |
| test.cpp:41:15:41:28 | ... + ... | test.cpp:41:15:41:28 | Store |
@@ -415,7 +335,6 @@ edges
| test.cpp:44:16:44:16 | Load | test.cpp:47:16:47:16 | Load |
| test.cpp:44:16:44:16 | Load | test.cpp:48:16:48:16 | Load |
| test.cpp:44:16:44:20 | ... + ... | test.cpp:44:14:44:21 | Load: * ... |
| test.cpp:44:16:44:20 | ... + ... | test.cpp:44:14:44:21 | Load: * ... |
| test.cpp:45:16:45:16 | Load | test.cpp:42:14:42:15 | Load: * ... |
| test.cpp:45:16:45:16 | Load | test.cpp:42:14:42:15 | Load: * ... |
| test.cpp:45:16:45:16 | Load | test.cpp:44:14:44:21 | Load: * ... |
@@ -438,8 +357,6 @@ edges
| test.cpp:47:16:47:16 | Load | test.cpp:44:14:44:21 | Load: * ... |
| test.cpp:47:16:47:16 | Load | test.cpp:48:16:48:16 | Load |
| test.cpp:48:16:48:16 | Load | test.cpp:42:14:42:15 | Load: * ... |
| test.cpp:48:16:48:16 | Load | test.cpp:42:14:42:15 | Load: * ... |
| test.cpp:48:16:48:16 | Load | test.cpp:44:14:44:21 | Load: * ... |
| test.cpp:48:16:48:16 | Load | test.cpp:44:14:44:21 | Load: * ... |
| test.cpp:51:7:51:14 | VariableAddress indirection | test.cpp:62:39:62:39 | Load |
| test.cpp:51:7:51:14 | VariableAddress indirection | test.cpp:66:39:66:39 | Load |
@@ -449,18 +366,13 @@ edges
| test.cpp:52:19:52:24 | call to malloc | test.cpp:53:12:53:16 | Load |
| test.cpp:53:5:53:23 | Store | test.cpp:51:33:51:35 | Load indirection |
| test.cpp:53:12:53:16 | Load | test.cpp:53:5:53:23 | Store |
| test.cpp:53:12:53:16 | Load | test.cpp:53:5:53:23 | Store |
| test.cpp:53:12:53:16 | Load | test.cpp:53:12:53:23 | ... + ... |
| test.cpp:53:12:53:16 | Load | test.cpp:53:12:53:23 | ... + ... |
| test.cpp:53:12:53:23 | ... + ... | test.cpp:51:33:51:35 | Load indirection |
| test.cpp:60:34:60:37 | mk_array output argument | test.cpp:62:32:62:34 | Load |
| test.cpp:60:34:60:37 | mk_array output argument | test.cpp:66:32:66:34 | Load |
| test.cpp:60:34:60:37 | mk_array output argument | test.cpp:70:31:70:33 | Load |
| test.cpp:62:32:62:34 | Load | test.cpp:67:9:67:14 | Store: ... = ... |
| test.cpp:62:32:62:34 | Load | test.cpp:67:9:67:14 | Store: ... = ... |
| test.cpp:66:32:66:34 | Load | test.cpp:67:9:67:14 | Store: ... = ... |
| test.cpp:66:32:66:34 | Load | test.cpp:67:9:67:14 | Store: ... = ... |
| test.cpp:70:31:70:33 | Load | test.cpp:67:9:67:14 | Store: ... = ... |
| test.cpp:70:31:70:33 | Load | test.cpp:67:9:67:14 | Store: ... = ... |
| test.cpp:80:9:80:16 | VariableAddress indirection [begin] | test.cpp:91:20:91:22 | arr indirection [begin] |
| test.cpp:80:9:80:16 | VariableAddress indirection [begin] | test.cpp:95:20:95:22 | arr indirection [begin] |
@@ -479,8 +391,6 @@ edges
| test.cpp:83:15:83:17 | arr indirection [begin] | test.cpp:83:19:83:23 | begin |
| test.cpp:83:15:83:30 | ... + ... | test.cpp:83:5:83:30 | Store |
| test.cpp:83:19:83:23 | Load | test.cpp:83:5:83:30 | Store |
| test.cpp:83:19:83:23 | Load | test.cpp:83:5:83:30 | Store |
| test.cpp:83:19:83:23 | Load | test.cpp:83:15:83:30 | ... + ... |
| test.cpp:83:19:83:23 | Load | test.cpp:83:15:83:30 | ... + ... |
| test.cpp:83:19:83:23 | begin | test.cpp:83:19:83:23 | Load |
| test.cpp:91:20:91:22 | arr indirection [begin] | test.cpp:91:24:91:28 | begin |
@@ -488,21 +398,18 @@ edges
| test.cpp:91:24:91:28 | begin | test.cpp:91:47:91:47 | Load |
| test.cpp:91:36:91:38 | arr indirection [end] | test.cpp:91:40:91:42 | end |
| test.cpp:91:40:91:42 | Load | test.cpp:96:9:96:14 | Store: ... = ... |
| test.cpp:91:40:91:42 | Load | test.cpp:96:9:96:14 | Store: ... = ... |
| test.cpp:91:40:91:42 | end | test.cpp:91:40:91:42 | Load |
| test.cpp:95:20:95:22 | arr indirection [begin] | test.cpp:95:24:95:28 | begin |
| test.cpp:95:20:95:22 | arr indirection [begin] | test.cpp:95:47:95:47 | Load |
| test.cpp:95:24:95:28 | begin | test.cpp:95:47:95:47 | Load |
| test.cpp:95:36:95:38 | arr indirection [end] | test.cpp:95:40:95:42 | end |
| test.cpp:95:40:95:42 | Load | test.cpp:96:9:96:14 | Store: ... = ... |
| test.cpp:95:40:95:42 | Load | test.cpp:96:9:96:14 | Store: ... = ... |
| test.cpp:95:40:95:42 | end | test.cpp:95:40:95:42 | Load |
| test.cpp:99:20:99:22 | arr indirection [begin] | test.cpp:99:24:99:28 | begin |
| test.cpp:99:20:99:22 | arr indirection [begin] | test.cpp:99:46:99:46 | Load |
| test.cpp:99:24:99:28 | begin | test.cpp:99:46:99:46 | Load |
| test.cpp:99:35:99:37 | arr indirection [end] | test.cpp:99:39:99:41 | end |
| test.cpp:99:39:99:41 | Load | test.cpp:96:9:96:14 | Store: ... = ... |
| test.cpp:99:39:99:41 | Load | test.cpp:96:9:96:14 | Store: ... = ... |
| test.cpp:99:39:99:41 | end | test.cpp:99:39:99:41 | Load |
| test.cpp:104:27:104:29 | arr [begin] | test.cpp:105:20:105:22 | arr indirection [begin] |
| test.cpp:104:27:104:29 | arr [begin] | test.cpp:109:20:109:22 | arr indirection [begin] |
@@ -515,21 +422,18 @@ edges
| test.cpp:105:24:105:28 | begin | test.cpp:105:47:105:47 | Load |
| test.cpp:105:36:105:38 | arr indirection [end] | test.cpp:105:40:105:42 | end |
| test.cpp:105:40:105:42 | Load | test.cpp:110:9:110:14 | Store: ... = ... |
| test.cpp:105:40:105:42 | Load | test.cpp:110:9:110:14 | Store: ... = ... |
| test.cpp:105:40:105:42 | end | test.cpp:105:40:105:42 | Load |
| test.cpp:109:20:109:22 | arr indirection [begin] | test.cpp:109:24:109:28 | begin |
| test.cpp:109:20:109:22 | arr indirection [begin] | test.cpp:109:47:109:47 | Load |
| test.cpp:109:24:109:28 | begin | test.cpp:109:47:109:47 | Load |
| test.cpp:109:36:109:38 | arr indirection [end] | test.cpp:109:40:109:42 | end |
| test.cpp:109:40:109:42 | Load | test.cpp:110:9:110:14 | Store: ... = ... |
| test.cpp:109:40:109:42 | Load | test.cpp:110:9:110:14 | Store: ... = ... |
| test.cpp:109:40:109:42 | end | test.cpp:109:40:109:42 | Load |
| test.cpp:113:20:113:22 | arr indirection [begin] | test.cpp:113:24:113:28 | begin |
| test.cpp:113:20:113:22 | arr indirection [begin] | test.cpp:113:46:113:46 | Load |
| test.cpp:113:24:113:28 | begin | test.cpp:113:46:113:46 | Load |
| test.cpp:113:35:113:37 | arr indirection [end] | test.cpp:113:39:113:41 | end |
| test.cpp:113:39:113:41 | Load | test.cpp:110:9:110:14 | Store: ... = ... |
| test.cpp:113:39:113:41 | Load | test.cpp:110:9:110:14 | Store: ... = ... |
| test.cpp:113:39:113:41 | end | test.cpp:113:39:113:41 | Load |
| test.cpp:119:18:119:25 | call to mk_array [begin] | test.cpp:104:27:104:29 | arr [begin] |
| test.cpp:119:18:119:25 | call to mk_array [end] | test.cpp:104:27:104:29 | arr [end] |
@@ -558,8 +462,6 @@ edges
| test.cpp:144:16:144:18 | Load indirection [begin] | test.cpp:144:21:144:25 | begin |
| test.cpp:144:16:144:32 | ... + ... | test.cpp:144:5:144:32 | Store |
| test.cpp:144:21:144:25 | Load | test.cpp:144:5:144:32 | Store |
| test.cpp:144:21:144:25 | Load | test.cpp:144:5:144:32 | Store |
| test.cpp:144:21:144:25 | Load | test.cpp:144:16:144:32 | ... + ... |
| test.cpp:144:21:144:25 | Load | test.cpp:144:16:144:32 | ... + ... |
| test.cpp:144:21:144:25 | begin | test.cpp:144:21:144:25 | Load |
| test.cpp:150:20:150:29 | Call indirection [begin] | test.cpp:152:20:152:22 | Load indirection [begin] |
@@ -574,7 +476,6 @@ edges
| test.cpp:156:25:156:29 | begin | test.cpp:156:49:156:49 | Load |
| test.cpp:156:37:156:39 | Load indirection [end] | test.cpp:156:42:156:44 | end |
| test.cpp:156:42:156:44 | Load | test.cpp:157:9:157:14 | Store: ... = ... |
| test.cpp:156:42:156:44 | Load | test.cpp:157:9:157:14 | Store: ... = ... |
| test.cpp:156:42:156:44 | end | test.cpp:156:42:156:44 | Load |
| test.cpp:160:20:160:22 | Load indirection [begin] | test.cpp:160:25:160:29 | begin |
| test.cpp:160:20:160:22 | Load indirection [begin] | test.cpp:160:48:160:48 | Load |
@@ -590,21 +491,18 @@ edges
| test.cpp:166:25:166:29 | begin | test.cpp:166:49:166:49 | Load |
| test.cpp:166:37:166:39 | Load indirection [end] | test.cpp:166:42:166:44 | end |
| test.cpp:166:42:166:44 | Load | test.cpp:171:9:171:14 | Store: ... = ... |
| test.cpp:166:42:166:44 | Load | test.cpp:171:9:171:14 | Store: ... = ... |
| test.cpp:166:42:166:44 | end | test.cpp:166:42:166:44 | Load |
| test.cpp:170:20:170:22 | Load indirection [begin] | test.cpp:170:25:170:29 | begin |
| test.cpp:170:20:170:22 | Load indirection [begin] | test.cpp:170:49:170:49 | Load |
| test.cpp:170:25:170:29 | begin | test.cpp:170:49:170:49 | Load |
| test.cpp:170:37:170:39 | Load indirection [end] | test.cpp:170:42:170:44 | end |
| test.cpp:170:42:170:44 | Load | test.cpp:171:9:171:14 | Store: ... = ... |
| test.cpp:170:42:170:44 | Load | test.cpp:171:9:171:14 | Store: ... = ... |
| test.cpp:170:42:170:44 | end | test.cpp:170:42:170:44 | Load |
| test.cpp:174:20:174:22 | Load indirection [begin] | test.cpp:174:25:174:29 | begin |
| test.cpp:174:20:174:22 | Load indirection [begin] | test.cpp:174:48:174:48 | Load |
| test.cpp:174:25:174:29 | begin | test.cpp:174:48:174:48 | Load |
| test.cpp:174:36:174:38 | Load indirection [end] | test.cpp:174:41:174:43 | end |
| test.cpp:174:41:174:43 | Load | test.cpp:171:9:171:14 | Store: ... = ... |
| test.cpp:174:41:174:43 | Load | test.cpp:171:9:171:14 | Store: ... = ... |
| test.cpp:174:41:174:43 | end | test.cpp:174:41:174:43 | Load |
| test.cpp:180:19:180:28 | call to mk_array_p indirection [begin] | test.cpp:165:29:165:31 | arr indirection [begin] |
| test.cpp:180:19:180:28 | call to mk_array_p indirection [end] | test.cpp:165:29:165:31 | arr indirection [end] |
@@ -614,19 +512,9 @@ edges
| test.cpp:194:23:194:28 | call to malloc | test.cpp:201:5:201:5 | Load |
| test.cpp:195:17:195:17 | Load | test.cpp:195:17:195:23 | ... + ... |
| test.cpp:195:17:195:17 | Load | test.cpp:195:17:195:23 | ... + ... |
| test.cpp:195:17:195:17 | Load | test.cpp:195:17:195:23 | ... + ... |
| test.cpp:195:17:195:17 | Load | test.cpp:195:17:195:23 | ... + ... |
| test.cpp:195:17:195:17 | Load | test.cpp:195:17:195:23 | Store |
| test.cpp:195:17:195:17 | Load | test.cpp:195:17:195:23 | Store |
| test.cpp:195:17:195:17 | Load | test.cpp:195:17:195:23 | Store |
| test.cpp:195:17:195:17 | Load | test.cpp:195:17:195:23 | Store |
| test.cpp:195:17:195:17 | Load | test.cpp:197:20:197:22 | Load |
| test.cpp:195:17:195:17 | Load | test.cpp:197:20:197:22 | Load |
| test.cpp:195:17:195:17 | Load | test.cpp:197:20:197:22 | Load |
| test.cpp:195:17:195:17 | Load | test.cpp:197:20:197:22 | Load |
| test.cpp:195:17:195:17 | Load | test.cpp:201:5:201:12 | access to array |
| test.cpp:195:17:195:17 | Load | test.cpp:201:5:201:12 | access to array |
| test.cpp:195:17:195:17 | Load | test.cpp:201:5:201:12 | access to array |
| test.cpp:195:17:195:17 | Load | test.cpp:201:5:201:12 | access to array |
| test.cpp:195:17:195:23 | ... + ... | test.cpp:195:17:195:23 | Store |
| test.cpp:195:17:195:23 | ... + ... | test.cpp:195:17:195:23 | Store |
@@ -637,29 +525,15 @@ edges
| test.cpp:195:17:195:23 | Store | test.cpp:201:5:201:19 | Store: ... = ... |
| test.cpp:195:17:195:23 | Store | test.cpp:201:5:201:19 | Store: ... = ... |
| test.cpp:197:20:197:22 | Load | test.cpp:201:5:201:19 | Store: ... = ... |
| test.cpp:197:20:197:22 | Load | test.cpp:201:5:201:19 | Store: ... = ... |
| test.cpp:201:5:201:12 | access to array | test.cpp:201:5:201:19 | Store: ... = ... |
| test.cpp:201:5:201:12 | access to array | test.cpp:201:5:201:19 | Store: ... = ... |
| test.cpp:205:23:205:28 | call to malloc | test.cpp:206:17:206:17 | Load |
| test.cpp:205:23:205:28 | call to malloc | test.cpp:208:15:208:15 | Load |
| test.cpp:206:17:206:17 | Load | test.cpp:206:17:206:23 | ... + ... |
| test.cpp:206:17:206:17 | Load | test.cpp:206:17:206:23 | ... + ... |
| test.cpp:206:17:206:17 | Load | test.cpp:206:17:206:23 | ... + ... |
| test.cpp:206:17:206:17 | Load | test.cpp:206:17:206:23 | ... + ... |
| test.cpp:206:17:206:17 | Load | test.cpp:206:17:206:23 | Store |
| test.cpp:206:17:206:17 | Load | test.cpp:206:17:206:23 | Store |
| test.cpp:206:17:206:17 | Load | test.cpp:206:17:206:23 | Store |
| test.cpp:206:17:206:17 | Load | test.cpp:206:17:206:23 | Store |
| test.cpp:206:17:206:17 | Load | test.cpp:209:12:209:14 | Load |
| test.cpp:206:17:206:17 | Load | test.cpp:209:12:209:14 | Load |
| test.cpp:206:17:206:17 | Load | test.cpp:209:12:209:14 | Load |
| test.cpp:206:17:206:17 | Load | test.cpp:209:12:209:14 | Load |
| test.cpp:206:17:206:17 | Load | test.cpp:213:5:213:6 | * ... |
| test.cpp:206:17:206:17 | Load | test.cpp:213:5:213:6 | * ... |
| test.cpp:206:17:206:17 | Load | test.cpp:213:5:213:6 | * ... |
| test.cpp:206:17:206:17 | Load | test.cpp:213:5:213:6 | * ... |
| test.cpp:206:17:206:17 | Load | test.cpp:213:6:213:6 | Load |
| test.cpp:206:17:206:17 | Load | test.cpp:213:6:213:6 | Load |
| test.cpp:206:17:206:17 | Load | test.cpp:213:6:213:6 | Load |
| test.cpp:206:17:206:17 | Load | test.cpp:213:6:213:6 | Load |
| test.cpp:206:17:206:23 | ... + ... | test.cpp:206:17:206:23 | Store |
@@ -671,8 +545,6 @@ edges
| test.cpp:206:17:206:23 | Store | test.cpp:213:5:213:13 | Store: ... = ... |
| test.cpp:206:17:206:23 | Store | test.cpp:213:5:213:13 | Store: ... = ... |
| test.cpp:209:12:209:14 | Load | test.cpp:213:5:213:13 | Store: ... = ... |
| test.cpp:209:12:209:14 | Load | test.cpp:213:5:213:13 | Store: ... = ... |
| test.cpp:213:5:213:6 | * ... | test.cpp:213:5:213:13 | Store: ... = ... |
| test.cpp:213:5:213:6 | * ... | test.cpp:213:5:213:13 | Store: ... = ... |
| test.cpp:213:6:213:6 | Load | test.cpp:213:5:213:6 | * ... |
| test.cpp:213:6:213:6 | Load | test.cpp:213:5:213:13 | Store: ... = ... |

View File

@@ -1,7 +1,7 @@
name: codeql/cpp-tests
groups: [cpp, test]
dependencies:
codeql/cpp-all: "*"
codeql/cpp-queries: "*"
codeql/cpp-all: ${workspace}
codeql/cpp-queries: ${workspace}
extractor: cpp
tests: .

View File

@@ -3,19 +3,20 @@
| nested.cpp:21:23:21:26 | fmt0 | The format string argument to snprintf should be constant to prevent security issues and other potential errors. |
| nested.cpp:79:32:79:38 | call to get_fmt | The format string argument to diagnostic should be constant to prevent security issues and other potential errors. |
| nested.cpp:87:18:87:20 | fmt | The format string argument to diagnostic should be constant to prevent security issues and other potential errors. |
| test.cpp:50:10:50:21 | call to make_message | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:56:12:56:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:59:12:59:21 | call to const_wash | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:60:12:60:26 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:61:12:61:17 | + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:62:12:62:18 | * ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:63:12:63:18 | & ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:64:12:64:39 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:66:10:66:35 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:69:12:69:20 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:75:12:75:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:81:12:81:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:87:12:87:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:92:12:92:18 | ++ ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:109:12:109:24 | new[] | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:129:20:129:26 | access to array | The format string argument to sprintf should be constant to prevent security issues and other potential errors. |
| test.cpp:51:10:51:21 | call to make_message | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:57:12:57:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:60:12:60:21 | call to const_wash | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:61:12:61:26 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:62:12:62:17 | + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:63:12:63:18 | * ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:64:12:64:18 | & ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:65:12:65:39 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:67:10:67:35 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:70:12:70:20 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:76:12:76:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:82:12:82:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:88:12:88:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:93:12:93:18 | ++ ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:110:12:110:24 | new[] | The format string argument to printf should be constant to prevent security issues and other potential errors. |
| test.cpp:130:20:130:26 | access to array | The format string argument to sprintf should be constant to prevent security issues and other potential errors. |
| test.cpp:157:12:157:15 | data | The format string argument to printf should be constant to prevent security issues and other potential errors. |

View File

@@ -1,6 +1,7 @@
extern "C" int printf(const char *fmt, ...);
extern "C" int sprintf(char *buf, const char *fmt, ...);
extern "C" char *gettext (const char *);
extern "C" char *gettext(const char *);
extern "C" char *strcpy(char *dst, const char *src);
#define MYSPRINTF sprintf
@@ -150,3 +151,8 @@ void print_ith_message() {
set_value_of(&i);
printf(messages[i], 1U); // GOOD
}
void fmt_via_strcpy(char *data) {
strcpy(data, "some string");
printf(data); // BAD
}

View File

@@ -12,11 +12,8 @@ nodes
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | semmle.label | ... + ... |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | semmle.label | fgets output argument |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... | semmle.label | (const char *)... |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... | semmle.label | (const char *)... |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | semmle.label | data |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | semmle.label | data |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | semmle.label | data |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | semmle.label | data indirection |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | semmle.label | data indirection |
#select
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | This argument to a file access function is derived from $@ and then passed to fopen(filename). | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | user input (fgets) |

View File

@@ -12,11 +12,8 @@ nodes
| test.c:9:23:9:26 | argv | semmle.label | argv |
| test.c:9:23:9:26 | argv | semmle.label | argv |
| test.c:17:11:17:18 | (const char *)... | semmle.label | (const char *)... |
| test.c:17:11:17:18 | (const char *)... | semmle.label | (const char *)... |
| test.c:17:11:17:18 | fileName | semmle.label | fileName |
| test.c:17:11:17:18 | fileName | semmle.label | fileName |
| test.c:17:11:17:18 | fileName | semmle.label | fileName |
| test.c:17:11:17:18 | fileName indirection | semmle.label | fileName indirection |
| test.c:17:11:17:18 | fileName indirection | semmle.label | fileName indirection |
#select
| test.c:17:11:17:18 | fileName | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:9:23:9:26 | argv | user input (argv) |

View File

@@ -29,18 +29,13 @@ nodes
| search.c:14:24:14:28 | *query | semmle.label | *query |
| search.c:14:24:14:28 | query | semmle.label | query |
| search.c:17:8:17:12 | (const char *)... | semmle.label | (const char *)... |
| search.c:17:8:17:12 | (const char *)... | semmle.label | (const char *)... |
| search.c:17:8:17:12 | query | semmle.label | query |
| search.c:17:8:17:12 | query | semmle.label | query |
| search.c:17:8:17:12 | query | semmle.label | query |
| search.c:17:8:17:12 | query indirection | semmle.label | query indirection |
| search.c:17:8:17:12 | query indirection | semmle.label | query indirection |
| search.c:22:24:22:28 | *query | semmle.label | *query |
| search.c:22:24:22:28 | query | semmle.label | query |
| search.c:23:39:23:43 | query | semmle.label | query |
| search.c:23:39:23:43 | query | semmle.label | query |
| search.c:23:39:23:43 | query | semmle.label | query |
| search.c:23:39:23:43 | query indirection | semmle.label | query indirection |
| 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 |

View File

@@ -18,18 +18,13 @@ nodes
| test.c:15:20:15:23 | argv | semmle.label | argv |
| test.c:15:20:15:23 | argv | semmle.label | argv |
| test.c:21:18:21:23 | (const char *)... | semmle.label | (const char *)... |
| test.c:21:18:21:23 | (const char *)... | semmle.label | (const char *)... |
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
| test.c:21:18:21:23 | query1 indirection | semmle.label | query1 indirection |
| test.c:21:18:21:23 | query1 indirection | semmle.label | query1 indirection |
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
| test.cpp:43:27:43:33 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:43:27:43:33 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
| test.cpp:43:27:43:33 | access to array indirection | semmle.label | access to array indirection |
| test.cpp:43:27:43:33 | access to array indirection | semmle.label | access to array indirection |
#select
| test.c:21:18:21:23 | query1 | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:15:20:15:23 | argv | user input (argv) |

View File

@@ -17,11 +17,8 @@ nodes
| test.cpp:37:73:37:76 | *data | semmle.label | *data |
| test.cpp:37:73:37:76 | data | semmle.label | data |
| test.cpp:43:32:43:35 | (LPCSTR)... | semmle.label | (LPCSTR)... |
| test.cpp:43:32:43:35 | (LPCSTR)... | semmle.label | (LPCSTR)... |
| test.cpp:43:32:43:35 | data | semmle.label | data |
| test.cpp:43:32:43:35 | data | semmle.label | data |
| test.cpp:43:32:43:35 | data | semmle.label | data |
| test.cpp:43:32:43:35 | data indirection | semmle.label | data indirection |
| 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 |

View File

@@ -79,15 +79,11 @@ nodes
| test.cpp:24:30:24:36 | command | semmle.label | command |
| test.cpp:26:10:26:16 | command | semmle.label | command |
| test.cpp:26:10:26:16 | command | semmle.label | command |
| test.cpp:26:10:26:16 | command | semmle.label | command |
| test.cpp:26:10:26:16 | command indirection | semmle.label | command indirection |
| test.cpp:26:10:26:16 | command indirection | semmle.label | command indirection |
| test.cpp:29:30:29:36 | *command | semmle.label | *command |
| test.cpp:29:30:29:36 | command | semmle.label | command |
| test.cpp:31:10:31:16 | command | semmle.label | command |
| test.cpp:31:10:31:16 | command | semmle.label | command |
| 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:18:42:23 | call to getenv | semmle.label | call to getenv |
| test.cpp:42:18:42:34 | (const char *)... | semmle.label | (const char *)... |
@@ -100,54 +96,36 @@ nodes
| test.cpp:56:12:56:17 | buffer | semmle.label | buffer |
| test.cpp:56:12:56:17 | fgets output argument | semmle.label | fgets output argument |
| test.cpp:62:10:62:15 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:62:10:62:15 | (const char *)... | semmle.label | (const char *)... |
| 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 *)... |
| test.cpp:78:10:78:15 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:78:10:78:15 | buffer | semmle.label | buffer |
| test.cpp:78:10:78:15 | buffer indirection | semmle.label | buffer indirection |
| test.cpp:78:10:78:15 | buffer indirection | semmle.label | buffer indirection |
| test.cpp:98:17:98:22 | buffer | semmle.label | buffer |
| test.cpp:98:17:98:22 | recv output argument | semmle.label | recv output argument |
| test.cpp:99:15:99:20 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:99:15:99:20 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:99:15:99:20 | buffer | semmle.label | buffer |
| test.cpp:99:15:99:20 | buffer indirection | semmle.label | buffer indirection |
| test.cpp:99:15:99:20 | buffer indirection | semmle.label | buffer indirection |
| test.cpp:106:17:106:22 | buffer | semmle.label | buffer |
| test.cpp:106:17:106:22 | recv output argument | semmle.label | recv output argument |
| test.cpp:107:15:107:20 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:107:15:107:20 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:107:15:107:20 | buffer | semmle.label | buffer |
| test.cpp:107:15:107:20 | buffer indirection | semmle.label | buffer indirection |
| test.cpp:107:15:107:20 | buffer indirection | semmle.label | buffer indirection |
#select
| 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 |

View File

@@ -56,42 +56,30 @@ nodes
| tests.c:28:22:28:25 | argv | semmle.label | argv |
| tests.c:28:22:28:25 | argv | semmle.label | argv |
| tests.c:28:22:28:28 | (const char *)... | semmle.label | (const char *)... |
| tests.c:28:22:28:28 | (const char *)... | semmle.label | (const char *)... |
| tests.c:28:22:28:28 | access to array | semmle.label | access to array |
| tests.c:28:22:28:28 | access to array | semmle.label | access to array |
| tests.c:28:22:28:28 | access to array | semmle.label | access to array |
| tests.c:28:22:28:28 | access to array indirection | semmle.label | access to array indirection |
| tests.c:28:22:28:28 | access to array indirection | semmle.label | access to array indirection |
| tests.c:29:28:29:31 | argv | semmle.label | argv |
| tests.c:29:28:29:31 | argv | semmle.label | argv |
| tests.c:29:28:29:34 | access to array | semmle.label | access to array |
| tests.c:29:28:29:34 | access to array | semmle.label | access to array |
| tests.c:29:28:29:34 | access to array | semmle.label | access to array |
| tests.c:29:28:29:34 | access to array indirection | semmle.label | access to array indirection |
| tests.c:29:28:29:34 | access to array indirection | semmle.label | access to array indirection |
| tests.c:31:15:31:23 | array to pointer conversion | semmle.label | array to pointer conversion |
| tests.c:31:15:31:23 | array to pointer conversion | semmle.label | array to pointer conversion |
| tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 |
| tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 |
| tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 |
| tests.c:31:15:31:23 | buffer100 indirection | semmle.label | buffer100 indirection |
| tests.c:31:15:31:23 | buffer100 indirection | semmle.label | buffer100 indirection |
| tests.c:31:15:31:23 | scanf output argument | semmle.label | scanf output argument |
| tests.c:33:21:33:29 | array to pointer conversion | semmle.label | array to pointer conversion |
| tests.c:33:21:33:29 | array to pointer conversion | semmle.label | array to pointer conversion |
| tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 |
| tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 |
| tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 |
| tests.c:33:21:33:29 | buffer100 indirection | semmle.label | buffer100 indirection |
| tests.c:33:21:33:29 | buffer100 indirection | semmle.label | buffer100 indirection |
| tests.c:34:10:34:13 | argv | semmle.label | argv |
| tests.c:34:10:34:13 | argv | semmle.label | argv |
| tests.c:34:10:34:16 | (const char *)... | semmle.label | (const char *)... |
| tests.c:34:10:34:16 | (const char *)... | semmle.label | (const char *)... |
| tests.c:34:10:34:16 | access to array | semmle.label | access to array |
| tests.c:34:10:34:16 | access to array | semmle.label | access to array |
| tests.c:34:10:34:16 | access to array | semmle.label | access to array |
| tests.c:34:10:34:16 | access to array indirection | semmle.label | access to array indirection |
| tests.c:34:10:34:16 | access to array indirection | semmle.label | access to array indirection |
#select
| tests.c:28:3:28:9 | call to sprintf | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv |

View File

@@ -27,26 +27,18 @@ nodes
| char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | semmle.label | ... + ... |
| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | semmle.label | data |
| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | semmle.label | data |
| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | semmle.label | data |
| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data indirection | semmle.label | data indirection |
| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data indirection | semmle.label | data indirection |
| char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | semmle.label | ... + ... |
| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | semmle.label | fgets output argument |
| char_console_fprintf_01_bad.c:49:21:49:24 | (const char *)... | semmle.label | (const char *)... |
| char_console_fprintf_01_bad.c:49:21:49:24 | (const char *)... | semmle.label | (const char *)... |
| char_console_fprintf_01_bad.c:49:21:49:24 | data | semmle.label | data |
| char_console_fprintf_01_bad.c:49:21:49:24 | data | semmle.label | data |
| char_console_fprintf_01_bad.c:49:21:49:24 | data | semmle.label | data |
| char_console_fprintf_01_bad.c:49:21:49:24 | data indirection | semmle.label | data indirection |
| char_console_fprintf_01_bad.c:49:21:49:24 | data indirection | semmle.label | data indirection |
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | semmle.label | call to getenv |
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | semmle.label | call to getenv |
| char_environment_fprintf_01_bad.c:36:21:36:24 | (const char *)... | semmle.label | (const char *)... |
| char_environment_fprintf_01_bad.c:36:21:36:24 | (const char *)... | semmle.label | (const char *)... |
| char_environment_fprintf_01_bad.c:36:21:36:24 | data | semmle.label | data |
| char_environment_fprintf_01_bad.c:36:21:36:24 | data | semmle.label | data |
| char_environment_fprintf_01_bad.c:36:21:36:24 | data | semmle.label | data |
| char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection | semmle.label | data indirection |
| char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection | semmle.label | data indirection |
#select
| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | The value of this argument may come from $@ and is being used as a formatting argument to badVaSink(data), which calls vsnprintf(format). | char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | recv |

View File

@@ -272,29 +272,20 @@ nodes
| argvLocal.c:95:9:95:12 | argv | semmle.label | argv |
| argvLocal.c:95:9:95:12 | argv | semmle.label | argv |
| argvLocal.c:95:9:95:15 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:95:9:95:15 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:95:9:95:15 | access to array | semmle.label | access to array |
| argvLocal.c:95:9:95:15 | access to array | semmle.label | access to array |
| argvLocal.c:95:9:95:15 | access to array | semmle.label | access to array |
| argvLocal.c:95:9:95:15 | access to array indirection | semmle.label | access to array indirection |
| argvLocal.c:95:9:95:15 | access to array indirection | semmle.label | access to array indirection |
| argvLocal.c:96:15:96:18 | argv | semmle.label | argv |
| argvLocal.c:96:15:96:18 | argv | semmle.label | argv |
| argvLocal.c:96:15:96:21 | access to array | semmle.label | access to array |
| argvLocal.c:96:15:96:21 | access to array | semmle.label | access to array |
| argvLocal.c:96:15:96:21 | access to array | semmle.label | access to array |
| argvLocal.c:96:15:96:21 | access to array indirection | semmle.label | access to array indirection |
| argvLocal.c:96:15:96:21 | access to array indirection | semmle.label | access to array indirection |
| argvLocal.c:100:7:100:10 | argv | semmle.label | argv |
| argvLocal.c:100:7:100:10 | argv | semmle.label | argv |
| argvLocal.c:101:9:101:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:101:9:101:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:101:9:101:10 | i1 | semmle.label | i1 |
| argvLocal.c:101:9:101:10 | i1 | semmle.label | i1 |
| argvLocal.c:101:9:101:10 | i1 | semmle.label | i1 |
| argvLocal.c:101:9:101:10 | i1 indirection | semmle.label | i1 indirection |
| argvLocal.c:101:9:101:10 | i1 indirection | semmle.label | i1 indirection |
| argvLocal.c:102:15:102:16 | i1 | semmle.label | i1 |
| argvLocal.c:102:15:102:16 | i1 | semmle.label | i1 |
| argvLocal.c:102:15:102:16 | i1 | semmle.label | i1 |
| argvLocal.c:102:15:102:16 | i1 indirection | semmle.label | i1 indirection |
@@ -303,51 +294,35 @@ nodes
| argvLocal.c:105:14:105:17 | argv | semmle.label | argv |
| argvLocal.c:105:14:105:17 | argv | semmle.label | argv |
| argvLocal.c:106:9:106:13 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:106:9:106:13 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:106:9:106:13 | access to array | semmle.label | access to array |
| argvLocal.c:106:9:106:13 | access to array | semmle.label | access to array |
| argvLocal.c:106:9:106:13 | access to array | semmle.label | access to array |
| argvLocal.c:106:9:106:13 | access to array indirection | semmle.label | access to array indirection |
| argvLocal.c:106:9:106:13 | access to array indirection | semmle.label | access to array indirection |
| argvLocal.c:107:15:107:19 | access to array | semmle.label | access to array |
| argvLocal.c:107:15:107:19 | access to array | semmle.label | access to array |
| argvLocal.c:107:15:107:19 | access to array | semmle.label | access to array |
| argvLocal.c:107:15:107:19 | access to array indirection | semmle.label | access to array indirection |
| argvLocal.c:107:15:107:19 | access to array indirection | semmle.label | access to array indirection |
| argvLocal.c:107:15:107:19 | printWrapper output argument | semmle.label | printWrapper output argument |
| argvLocal.c:110:9:110:11 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:110:9:110:11 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:110:9:110:11 | * ... | semmle.label | * ... |
| argvLocal.c:110:9:110:11 | * ... | semmle.label | * ... |
| argvLocal.c:110:9:110:11 | * ... | semmle.label | * ... |
| argvLocal.c:110:9:110:11 | * ... indirection | semmle.label | * ... indirection |
| argvLocal.c:110:9:110:11 | * ... indirection | semmle.label | * ... indirection |
| argvLocal.c:111:15:111:17 | * ... | semmle.label | * ... |
| argvLocal.c:111:15:111:17 | * ... | semmle.label | * ... |
| argvLocal.c:111:15:111:17 | * ... | semmle.label | * ... |
| argvLocal.c:111:15:111:17 | * ... indirection | semmle.label | * ... indirection |
| argvLocal.c:111:15:111:17 | * ... indirection | semmle.label | * ... indirection |
| argvLocal.c:115:13:115:16 | argv | semmle.label | argv |
| argvLocal.c:115:13:115:16 | argv | semmle.label | argv |
| argvLocal.c:116:9:116:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:116:9:116:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:116:9:116:10 | i3 | semmle.label | i3 |
| argvLocal.c:116:9:116:10 | i3 indirection | semmle.label | i3 indirection |
| argvLocal.c:116:9:116:10 | i3 indirection | semmle.label | i3 indirection |
| argvLocal.c:117:15:117:16 | array to pointer conversion | semmle.label | array to pointer conversion |
| argvLocal.c:117:15:117:16 | array to pointer conversion | semmle.label | array to pointer conversion |
| argvLocal.c:117:15:117:16 | i3 | semmle.label | i3 |
| argvLocal.c:117:15:117:16 | i3 indirection | semmle.label | i3 indirection |
| argvLocal.c:117:15:117:16 | i3 indirection | semmle.label | i3 indirection |
| argvLocal.c:117:15:117:16 | printWrapper output argument | semmle.label | printWrapper output argument |
| 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 |
| argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 |
| argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 |
| argvLocal.c:122:15:122:16 | i4 indirection | semmle.label | i4 indirection |
@@ -356,108 +331,69 @@ nodes
| argvLocal.c:126:10:126:13 | argv | semmle.label | argv |
| argvLocal.c:126:10:126:13 | argv | semmle.label | argv |
| argvLocal.c:127:9:127:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:127:9:127:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:127:9:127:10 | i5 | semmle.label | i5 |
| argvLocal.c:127:9:127:10 | i5 indirection | semmle.label | i5 indirection |
| argvLocal.c:127:9:127:10 | i5 indirection | semmle.label | i5 indirection |
| argvLocal.c:128:15:128:16 | array to pointer conversion | semmle.label | array to pointer conversion |
| argvLocal.c:128:15:128:16 | array to pointer conversion | semmle.label | array to pointer conversion |
| argvLocal.c:128:15:128:16 | i5 | semmle.label | i5 |
| argvLocal.c:128:15:128:16 | i5 indirection | semmle.label | i5 indirection |
| argvLocal.c:128:15:128:16 | i5 indirection | semmle.label | i5 indirection |
| argvLocal.c:128:15:128:16 | printWrapper output argument | semmle.label | printWrapper output argument |
| argvLocal.c:131:9:131:14 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:131:9:131:14 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:131:9:131:14 | ... + ... | semmle.label | ... + ... |
| argvLocal.c:131:9:131:14 | ... + ... indirection | semmle.label | ... + ... indirection |
| argvLocal.c:131:9:131:14 | ... + ... indirection | semmle.label | ... + ... indirection |
| argvLocal.c:132:15:132:20 | ... + ... | semmle.label | ... + ... |
| argvLocal.c:132:15:132:20 | ... + ... | semmle.label | ... + ... |
| argvLocal.c:132:15:132:20 | ... + ... | semmle.label | ... + ... |
| argvLocal.c:132:15:132:20 | ... + ... indirection | semmle.label | ... + ... indirection |
| argvLocal.c:132:15:132:20 | ... + ... indirection | semmle.label | ... + ... indirection |
| argvLocal.c:135:9:135:10 | i4 | semmle.label | i4 |
| argvLocal.c:135:9:135:10 | i4 | semmle.label | i4 |
| argvLocal.c:135:9:135:12 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:135:9:135:12 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:135:9:135:12 | ... ++ | semmle.label | ... ++ |
| argvLocal.c:135:9:135:12 | ... ++ | semmle.label | ... ++ |
| argvLocal.c:135:9:135:12 | ... ++ | semmle.label | ... ++ |
| argvLocal.c:135:9:135:12 | ... ++ indirection | semmle.label | ... ++ indirection |
| argvLocal.c:135:9:135:12 | ... ++ indirection | semmle.label | ... ++ indirection |
| argvLocal.c:136:15:136:18 | -- ... | semmle.label | -- ... |
| argvLocal.c:136:15:136:18 | -- ... | semmle.label | -- ... |
| argvLocal.c:136:15:136:18 | -- ... | semmle.label | -- ... |
| argvLocal.c:136:15:136:18 | -- ... indirection | semmle.label | -- ... indirection |
| argvLocal.c:136:15:136:18 | -- ... indirection | semmle.label | -- ... indirection |
| argvLocal.c:136:17:136:18 | i4 | semmle.label | i4 |
| argvLocal.c:136:17:136:18 | i4 | semmle.label | i4 |
| argvLocal.c:144:9:144:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:144:9:144:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:144:9:144:10 | i7 | semmle.label | i7 |
| argvLocal.c:144:9:144:10 | i7 | semmle.label | i7 |
| argvLocal.c:144:9:144:10 | i7 | semmle.label | i7 |
| argvLocal.c:144:9:144:10 | i7 indirection | semmle.label | i7 indirection |
| argvLocal.c:144:9:144:10 | i7 indirection | semmle.label | i7 indirection |
| argvLocal.c:145:15:145:16 | i7 | semmle.label | i7 |
| argvLocal.c:145:15:145:16 | i7 | semmle.label | i7 |
| argvLocal.c:145:15:145:16 | i7 | semmle.label | i7 |
| argvLocal.c:145:15:145:16 | i7 indirection | semmle.label | i7 indirection |
| argvLocal.c:145:15:145:16 | i7 indirection | semmle.label | i7 indirection |
| argvLocal.c:149:11:149:14 | argv | semmle.label | argv |
| argvLocal.c:149:11:149:14 | argv | semmle.label | argv |
| argvLocal.c:150:9:150:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:150:9:150:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:150:9:150:10 | i8 | semmle.label | i8 |
| argvLocal.c:150:9:150:10 | i8 | semmle.label | i8 |
| argvLocal.c:150:9:150:10 | i8 | semmle.label | i8 |
| argvLocal.c:150:9:150:10 | i8 indirection | semmle.label | i8 indirection |
| argvLocal.c:150:9:150:10 | i8 indirection | semmle.label | i8 indirection |
| argvLocal.c:151:15:151:16 | i8 | semmle.label | i8 |
| argvLocal.c:151:15:151:16 | i8 | semmle.label | i8 |
| argvLocal.c:151:15:151:16 | i8 | semmle.label | i8 |
| argvLocal.c:151:15:151:16 | i8 indirection | semmle.label | i8 indirection |
| argvLocal.c:151:15:151:16 | i8 indirection | semmle.label | i8 indirection |
| argvLocal.c:156:23:156:26 | argv | semmle.label | argv |
| argvLocal.c:156:23:156:26 | argv | semmle.label | argv |
| argvLocal.c:157:9:157:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:157:9:157:10 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:157:9:157:10 | i9 | semmle.label | i9 |
| argvLocal.c:157:9:157:10 | i9 indirection | semmle.label | i9 indirection |
| argvLocal.c:157:9:157:10 | i9 indirection | semmle.label | i9 indirection |
| argvLocal.c:158:15:158:16 | i9 | semmle.label | i9 |
| argvLocal.c:158:15:158:16 | i9 | semmle.label | i9 |
| argvLocal.c:158:15:158:16 | i9 | semmle.label | i9 |
| argvLocal.c:158:15:158:16 | i9 indirection | semmle.label | i9 indirection |
| argvLocal.c:158:15:158:16 | i9 indirection | semmle.label | i9 indirection |
| argvLocal.c:163:22:163:25 | argv | semmle.label | argv |
| argvLocal.c:163:22:163:25 | argv | semmle.label | argv |
| argvLocal.c:164:9:164:11 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:164:9:164:11 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:164:9:164:11 | i91 | semmle.label | i91 |
| argvLocal.c:164:9:164:11 | i91 indirection | semmle.label | i91 indirection |
| argvLocal.c:164:9:164:11 | i91 indirection | semmle.label | i91 indirection |
| argvLocal.c:165:15:165:17 | i91 | semmle.label | i91 |
| argvLocal.c:165:15:165:17 | i91 | semmle.label | i91 |
| argvLocal.c:165:15:165:17 | i91 | semmle.label | i91 |
| argvLocal.c:165:15:165:17 | i91 indirection | semmle.label | i91 indirection |
| argvLocal.c:165:15:165:17 | i91 indirection | semmle.label | i91 indirection |
| argvLocal.c:168:18:168:21 | argv | semmle.label | argv |
| argvLocal.c:168:18:168:21 | argv | semmle.label | argv |
| argvLocal.c:169:9:169:20 | (char *)... | semmle.label | (char *)... |
| argvLocal.c:169:9:169:20 | (char *)... | semmle.label | (char *)... |
| argvLocal.c:169:9:169:20 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:169:9:169:20 | (const char *)... | semmle.label | (const char *)... |
| argvLocal.c:169:9:169:20 | i10 indirection | semmle.label | i10 indirection |
| argvLocal.c:169:9:169:20 | i10 indirection | semmle.label | i10 indirection |
| argvLocal.c:169:18:169:20 | i10 | semmle.label | i10 |
| argvLocal.c:169:18:169:20 | i10 | semmle.label | i10 |
| argvLocal.c:169:18:169:20 | i10 | semmle.label | i10 |
| argvLocal.c:170:15:170:26 | (char *)... | semmle.label | (char *)... |
| argvLocal.c:170:15:170:26 | (char *)... | semmle.label | (char *)... |
| argvLocal.c:170:15:170:26 | i10 indirection | semmle.label | i10 indirection |
| argvLocal.c:170:15:170:26 | i10 indirection | semmle.label | i10 indirection |
| argvLocal.c:170:24:170:26 | i10 | semmle.label | i10 |
| argvLocal.c:170:24:170:26 | i10 | semmle.label | i10 |
| argvLocal.c:170:24:170:26 | i10 | semmle.label | i10 |
#select

View File

@@ -83,70 +83,50 @@ nodes
| funcsLocal.c:16:8:16:9 | fread output argument | semmle.label | fread output argument |
| funcsLocal.c:16:8:16:9 | i1 | semmle.label | i1 |
| funcsLocal.c:17:9:17:10 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:17:9:17:10 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:17:9:17:10 | i1 | semmle.label | i1 |
| funcsLocal.c:17:9:17:10 | i1 indirection | semmle.label | i1 indirection |
| funcsLocal.c:17:9:17:10 | i1 indirection | semmle.label | i1 indirection |
| funcsLocal.c:26:8:26:9 | fgets output argument | semmle.label | fgets output argument |
| funcsLocal.c:26:8:26:9 | i3 | semmle.label | i3 |
| funcsLocal.c:27:9:27:10 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:27:9:27:10 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:27:9:27:10 | i3 | semmle.label | i3 |
| funcsLocal.c:27:9:27:10 | i3 indirection | semmle.label | i3 indirection |
| funcsLocal.c:27:9:27:10 | i3 indirection | semmle.label | i3 indirection |
| funcsLocal.c:31:13:31:17 | call to fgets | semmle.label | call to fgets |
| funcsLocal.c:31:13:31:17 | call to fgets | semmle.label | call to fgets |
| funcsLocal.c:31:19:31:21 | fgets output argument | semmle.label | fgets output argument |
| funcsLocal.c:31:19:31:21 | i41 | semmle.label | i41 |
| funcsLocal.c:32:9:32:10 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:32:9:32:10 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:32:9:32:10 | i4 | semmle.label | i4 |
| funcsLocal.c:32:9:32:10 | i4 | semmle.label | i4 |
| funcsLocal.c:32:9:32:10 | i4 | semmle.label | i4 |
| funcsLocal.c:32:9:32:10 | i4 indirection | semmle.label | i4 indirection |
| funcsLocal.c:32:9:32:10 | i4 indirection | semmle.label | i4 indirection |
| funcsLocal.c:36:7:36:8 | gets output argument | semmle.label | gets output argument |
| funcsLocal.c:36:7:36:8 | i5 | semmle.label | i5 |
| funcsLocal.c:37:9:37:10 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:37:9:37:10 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:37:9:37:10 | i5 | semmle.label | i5 |
| funcsLocal.c:37:9:37:10 | i5 indirection | semmle.label | i5 indirection |
| funcsLocal.c:37:9:37:10 | i5 indirection | semmle.label | i5 indirection |
| funcsLocal.c:41:13:41:16 | call to gets | semmle.label | call to gets |
| funcsLocal.c:41:13:41:16 | call to gets | semmle.label | call to gets |
| funcsLocal.c:41:18:41:20 | gets output argument | semmle.label | gets output argument |
| funcsLocal.c:41:18:41:20 | i61 | semmle.label | i61 |
| funcsLocal.c:42:9:42:10 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:42:9:42:10 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 |
| funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 |
| funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 |
| funcsLocal.c:42:9:42:10 | i6 indirection | semmle.label | i6 indirection |
| funcsLocal.c:42:9:42:10 | i6 indirection | semmle.label | i6 indirection |
| funcsLocal.c:46:7:46:9 | * ... | semmle.label | * ... |
| funcsLocal.c:46:7:46:9 | * ... | semmle.label | * ... |
| funcsLocal.c:46:7:46:9 | gets output argument | semmle.label | gets output argument |
| funcsLocal.c:47:9:47:11 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:47:9:47:11 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:47:9:47:11 | * ... | semmle.label | * ... |
| funcsLocal.c:47:9:47:11 | * ... | semmle.label | * ... |
| funcsLocal.c:47:9:47:11 | * ... | semmle.label | * ... |
| funcsLocal.c:47:9:47:11 | * ... indirection | semmle.label | * ... indirection |
| funcsLocal.c:47:9:47:11 | * ... indirection | semmle.label | * ... indirection |
| funcsLocal.c:52:8:52:11 | call to gets | semmle.label | call to gets |
| funcsLocal.c:52:8:52:11 | call to gets | semmle.label | call to gets |
| funcsLocal.c:53:9:53:11 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:53:9:53:11 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:53:9:53:11 | * ... | semmle.label | * ... |
| funcsLocal.c:53:9:53:11 | * ... | semmle.label | * ... |
| funcsLocal.c:53:9:53:11 | * ... | semmle.label | * ... |
| funcsLocal.c:53:9:53:11 | * ... indirection | semmle.label | * ... indirection |
| funcsLocal.c:53:9:53:11 | * ... indirection | semmle.label | * ... indirection |
| funcsLocal.c:58:9:58:10 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:58:9:58:10 | (const char *)... | semmle.label | (const char *)... |
| funcsLocal.c:58:9:58:10 | e1 | semmle.label | e1 |
| funcsLocal.c:58:9:58:10 | e1 indirection | semmle.label | e1 indirection |
| funcsLocal.c:58:9:58:10 | e1 indirection | semmle.label | e1 indirection |
#select
| funcsLocal.c:17:9:17:10 | i1 | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:16:8:16:9 | i1 | fread |
| funcsLocal.c:27:9:27:10 | i3 | funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:26:8:26:9 | i3 | fgets |

View File

@@ -90,12 +90,10 @@ nodes
| globalVars.c:24:11:24:14 | argv | semmle.label | argv |
| globalVars.c:24:11:24:14 | argv indirection | semmle.label | argv indirection |
| globalVars.c:27:9:27:12 | (const char *)... | semmle.label | (const char *)... |
| globalVars.c:27:9:27:12 | (const char *)... | semmle.label | (const char *)... |
| globalVars.c:27:9:27:12 | copy | semmle.label | copy |
| globalVars.c:27:9:27:12 | copy | semmle.label | copy |
| globalVars.c:27:9:27:12 | copy | semmle.label | copy |
| globalVars.c:27:9:27:12 | copy indirection | semmle.label | copy indirection |
| globalVars.c:27:9:27:12 | copy indirection | semmle.label | copy indirection |
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
@@ -106,12 +104,10 @@ nodes
| 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 *)... |
| globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 |
| globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 |
| globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 |
| globalVars.c:38:9:38:13 | copy2 indirection | semmle.label | copy2 indirection |
| globalVars.c:38:9:38:13 | copy2 indirection | semmle.label | copy2 indirection |
| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
@@ -120,12 +116,10 @@ nodes
| globalVars.c:41:15:41:19 | printWrapper output argument | semmle.label | printWrapper output argument |
| globalVars.c:44:15:44:19 | copy2 | semmle.label | copy2 |
| globalVars.c:50:9:50:13 | (const char *)... | semmle.label | (const char *)... |
| globalVars.c:50:9:50:13 | (const char *)... | semmle.label | (const char *)... |
| globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |
| globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |
| globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |
| globalVars.c:50:9:50:13 | copy2 indirection | semmle.label | copy2 indirection |
| globalVars.c:50:9:50:13 | copy2 indirection | semmle.label | copy2 indirection |
#select
| globalVars.c:27:9:27:12 | copy | globalVars.c:24:11:24:14 | argv | globalVars.c:27:9:27:12 | copy | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:24:11:24:14 | argv | argv |
| globalVars.c:30:15:30:18 | copy | globalVars.c:24:11:24:14 | argv | globalVars.c:30:15:30:18 | copy | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(str), which calls printf(format). | globalVars.c:24:11:24:14 | argv | argv |

View File

@@ -90,12 +90,10 @@ nodes
| globalVars.c:24:11:24:14 | argv | semmle.label | argv |
| globalVars.c:24:11:24:14 | argv indirection | semmle.label | argv indirection |
| globalVars.c:27:9:27:12 | (const char *)... | semmle.label | (const char *)... |
| globalVars.c:27:9:27:12 | (const char *)... | semmle.label | (const char *)... |
| globalVars.c:27:9:27:12 | copy | semmle.label | copy |
| globalVars.c:27:9:27:12 | copy | semmle.label | copy |
| globalVars.c:27:9:27:12 | copy | semmle.label | copy |
| globalVars.c:27:9:27:12 | copy indirection | semmle.label | copy indirection |
| globalVars.c:27:9:27:12 | copy indirection | semmle.label | copy indirection |
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
@@ -106,12 +104,10 @@ nodes
| 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 *)... |
| globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 |
| globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 |
| globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 |
| globalVars.c:38:9:38:13 | copy2 indirection | semmle.label | copy2 indirection |
| globalVars.c:38:9:38:13 | copy2 indirection | semmle.label | copy2 indirection |
| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
@@ -120,12 +116,10 @@ nodes
| globalVars.c:41:15:41:19 | printWrapper output argument | semmle.label | printWrapper output argument |
| globalVars.c:44:15:44:19 | copy2 | semmle.label | copy2 |
| globalVars.c:50:9:50:13 | (const char *)... | semmle.label | (const char *)... |
| globalVars.c:50:9:50:13 | (const char *)... | semmle.label | (const char *)... |
| globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |
| globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |
| globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |
| globalVars.c:50:9:50:13 | copy2 indirection | semmle.label | copy2 indirection |
| globalVars.c:50:9:50:13 | copy2 indirection | semmle.label | copy2 indirection |
#select
| globalVars.c:27:9:27:12 | copy | globalVars.c:24:11:24:14 | argv | globalVars.c:27:9:27:12 | copy | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:24:11:24:14 | argv | argv |
| globalVars.c:30:15:30:18 | copy | globalVars.c:24:11:24:14 | argv | globalVars.c:30:15:30:18 | copy | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(str), which calls printf(format). | globalVars.c:24:11:24:14 | argv | argv |

View File

@@ -92,101 +92,68 @@ nodes
| ifs.c:61:8:61:11 | argv | semmle.label | argv |
| ifs.c:61:8:61:11 | argv | semmle.label | argv |
| ifs.c:62:9:62:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:62:9:62:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:62:9:62:10 | c7 | semmle.label | c7 |
| ifs.c:62:9:62:10 | c7 | semmle.label | c7 |
| ifs.c:62:9:62:10 | c7 | semmle.label | c7 |
| ifs.c:62:9:62:10 | c7 indirection | semmle.label | c7 indirection |
| ifs.c:62:9:62:10 | c7 indirection | semmle.label | c7 indirection |
| ifs.c:68:8:68:11 | argv | semmle.label | argv |
| ifs.c:68:8:68:11 | argv | semmle.label | argv |
| ifs.c:69:9:69:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:69:9:69:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:69:9:69:10 | c8 | semmle.label | c8 |
| ifs.c:69:9:69:10 | c8 | semmle.label | c8 |
| ifs.c:69:9:69:10 | c8 | semmle.label | c8 |
| ifs.c:69:9:69:10 | c8 indirection | semmle.label | c8 indirection |
| ifs.c:69:9:69:10 | c8 indirection | semmle.label | c8 indirection |
| ifs.c:74:8:74:11 | argv | semmle.label | argv |
| ifs.c:74:8:74:11 | argv | semmle.label | argv |
| ifs.c:75:9:75:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:75:9:75:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:75:9:75:10 | i1 | semmle.label | i1 |
| ifs.c:75:9:75:10 | i1 | semmle.label | i1 |
| ifs.c:75:9:75:10 | i1 | semmle.label | i1 |
| ifs.c:75:9:75:10 | i1 indirection | semmle.label | i1 indirection |
| ifs.c:75:9:75:10 | i1 indirection | semmle.label | i1 indirection |
| ifs.c:80:8:80:11 | argv | semmle.label | argv |
| ifs.c:80:8:80:11 | argv | semmle.label | argv |
| ifs.c:81:9:81:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:81:9:81:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:81:9:81:10 | i2 | semmle.label | i2 |
| ifs.c:81:9:81:10 | i2 | semmle.label | i2 |
| ifs.c:81:9:81:10 | i2 | semmle.label | i2 |
| ifs.c:81:9:81:10 | i2 indirection | semmle.label | i2 indirection |
| ifs.c:81:9:81:10 | i2 indirection | semmle.label | i2 indirection |
| ifs.c:86:8:86:11 | argv | semmle.label | argv |
| ifs.c:86:8:86:11 | argv | semmle.label | argv |
| ifs.c:87:9:87:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:87:9:87:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:87:9:87:10 | i3 | semmle.label | i3 |
| ifs.c:87:9:87:10 | i3 | semmle.label | i3 |
| ifs.c:87:9:87:10 | i3 | semmle.label | i3 |
| ifs.c:87:9:87:10 | i3 indirection | semmle.label | i3 indirection |
| ifs.c:87:9:87:10 | i3 indirection | semmle.label | i3 indirection |
| ifs.c:92:8:92:11 | argv | semmle.label | argv |
| ifs.c:92:8:92:11 | argv | semmle.label | argv |
| ifs.c:93:9:93:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:93:9:93:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:93:9:93:10 | i4 | semmle.label | i4 |
| ifs.c:93:9:93:10 | i4 | semmle.label | i4 |
| ifs.c:93:9:93:10 | i4 | semmle.label | i4 |
| ifs.c:93:9:93:10 | i4 indirection | semmle.label | i4 indirection |
| ifs.c:93:9:93:10 | i4 indirection | semmle.label | i4 indirection |
| ifs.c:98:8:98:11 | argv | semmle.label | argv |
| ifs.c:98:8:98:11 | argv | semmle.label | argv |
| ifs.c:99:9:99:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:99:9:99:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:99:9:99:10 | i5 | semmle.label | i5 |
| ifs.c:99:9:99:10 | i5 | semmle.label | i5 |
| ifs.c:99:9:99:10 | i5 | semmle.label | i5 |
| ifs.c:99:9:99:10 | i5 indirection | semmle.label | i5 indirection |
| ifs.c:99:9:99:10 | i5 indirection | semmle.label | i5 indirection |
| ifs.c:105:8:105:11 | argv | semmle.label | argv |
| ifs.c:105:8:105:11 | argv | semmle.label | argv |
| ifs.c:106:9:106:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:106:9:106:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:106:9:106:10 | i6 | semmle.label | i6 |
| ifs.c:106:9:106:10 | i6 | semmle.label | i6 |
| ifs.c:106:9:106:10 | i6 | semmle.label | i6 |
| ifs.c:106:9:106:10 | i6 indirection | semmle.label | i6 indirection |
| ifs.c:106:9:106:10 | i6 indirection | semmle.label | i6 indirection |
| ifs.c:111:8:111:11 | argv | semmle.label | argv |
| ifs.c:111:8:111:11 | argv | semmle.label | argv |
| ifs.c:112:9:112:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:112:9:112:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:112:9:112:10 | i7 | semmle.label | i7 |
| ifs.c:112:9:112:10 | i7 | semmle.label | i7 |
| ifs.c:112:9:112:10 | i7 | semmle.label | i7 |
| ifs.c:112:9:112:10 | i7 indirection | semmle.label | i7 indirection |
| ifs.c:112:9:112:10 | i7 indirection | semmle.label | i7 indirection |
| ifs.c:117:8:117:11 | argv | semmle.label | argv |
| ifs.c:117:8:117:11 | argv | semmle.label | argv |
| ifs.c:118:9:118:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:118:9:118:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:118:9:118:10 | i8 | semmle.label | i8 |
| ifs.c:118:9:118:10 | i8 | semmle.label | i8 |
| ifs.c:118:9:118:10 | i8 | semmle.label | i8 |
| ifs.c:118:9:118:10 | i8 indirection | semmle.label | i8 indirection |
| ifs.c:118:9:118:10 | i8 indirection | semmle.label | i8 indirection |
| ifs.c:123:8:123:11 | argv | semmle.label | argv |
| ifs.c:123:8:123:11 | argv | semmle.label | argv |
| ifs.c:124:9:124:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:124:9:124:10 | (const char *)... | semmle.label | (const char *)... |
| ifs.c:124:9:124:10 | i9 | semmle.label | i9 |
| ifs.c:124:9:124:10 | i9 | semmle.label | i9 |
| ifs.c:124:9:124:10 | i9 | semmle.label | i9 |
| ifs.c:124:9:124:10 | i9 indirection | semmle.label | i9 indirection |
| ifs.c:124:9:124:10 | i9 indirection | semmle.label | i9 indirection |
#select
| ifs.c:62:9:62:10 | c7 | ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:61:8:61:11 | argv | argv |

View File

@@ -9,6 +9,5 @@ nodes
| examples.cpp:63:26:63:30 | fscanf output argument | semmle.label | fscanf output argument |
| examples.cpp:66:11:66:14 | data | semmle.label | data |
| examples.cpp:66:11:66:14 | data | semmle.label | data |
| examples.cpp:66:11:66:14 | data | semmle.label | data |
#select
| examples.cpp:66:11:66:14 | data | examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | examples.cpp:63:26:63:30 | & ... | User-provided value |

View File

@@ -28,7 +28,6 @@ nodes
| test2.cpp:12:21:12:21 | v | semmle.label | v |
| test2.cpp:14:11:14:11 | v | semmle.label | v |
| test2.cpp:14:11:14:11 | v | semmle.label | v |
| 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:13:27:13 | v | semmle.label | v |
@@ -37,26 +36,21 @@ nodes
| test5.cpp:9:7:9:9 | gets output argument | semmle.label | gets output argument |
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
| test5.cpp:18:6:18:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
| test5.cpp:19:6:19:6 | y | semmle.label | y |
| test5.cpp:19:6:19:6 | y | semmle.label | y |
| test5.cpp:19:6:19:6 | y | semmle.label | y |
| test.c:11:29:11:32 | argv | semmle.label | argv |
| test.c:11:29:11:32 | argv | semmle.label | argv |
| test.c:14:15:14:28 | maxConnections | semmle.label | maxConnections |
| test.c:14:15:14:28 | maxConnections | semmle.label | maxConnections |
| test.c:14:15:14:28 | maxConnections | semmle.label | maxConnections |
| test.c:41:17:41:20 | argv | semmle.label | argv |
| test.c:41:17:41:20 | argv | semmle.label | argv |
| test.c:44:7:44:10 | len2 | semmle.label | len2 |
| test.c:44:7:44:10 | len2 | semmle.label | len2 |
| test.c:44:7:44:10 | len2 | semmle.label | len2 |
| test.c:51:17:51:20 | argv | semmle.label | argv |
| test.c:51:17:51:20 | argv | semmle.label | argv |
| test.c:54:7:54:10 | len3 | semmle.label | len3 |
| test.c:54:7:54:10 | len3 | semmle.label | len3 |
| test.c:54:7:54:10 | len3 | semmle.label | len3 |
#select
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | & ... | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | & ... | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |

View File

@@ -2,7 +2,7 @@
name: codeql/cpp-tests-cwe-190-tainted
groups: [cpp, test]
dependencies:
codeql/cpp-all: "*"
codeql/cpp-queries: "*"
codeql/cpp-all: ${workspace}
codeql/cpp-queries: ${workspace}
extractor: cpp
tests: .

View File

@@ -23,22 +23,16 @@ nodes
| test.cpp:16:25:16:42 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:20:14:20:20 | address | semmle.label | address |
| test.cpp:20:14:20:20 | address | semmle.label | address |
| test.cpp:20:14:20:20 | address | semmle.label | address |
| test.cpp:20:14:20:20 | address indirection | semmle.label | address indirection |
| test.cpp:20:14:20:20 | address indirection | semmle.label | address indirection |
| test.cpp:27:25:27:30 | call to getenv | semmle.label | call to getenv |
| test.cpp:27:25:27:42 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:31:14:31:20 | address | semmle.label | address |
| test.cpp:31:14:31:20 | address | semmle.label | address |
| test.cpp:31:14:31:20 | address | semmle.label | address |
| test.cpp:31:14:31:20 | address indirection | semmle.label | address indirection |
| test.cpp:31:14:31:20 | address indirection | semmle.label | address indirection |
| test.cpp:38:25:38:30 | call to getenv | semmle.label | call to getenv |
| test.cpp:38:25:38:42 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:42:14:42:20 | address | semmle.label | address |
| test.cpp:42:14:42:20 | address | semmle.label | address |
| test.cpp:42:14:42:20 | address | semmle.label | address |
| test.cpp:42:14:42:20 | address indirection | semmle.label | address indirection |
| test.cpp:42:14:42:20 | address indirection | semmle.label | address indirection |
#select
| test.cpp:20:7:20:12 | call to strcmp | test.cpp:16:25:16:30 | call to getenv | test.cpp:20:14:20:20 | address | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:16:25:16:30 | call to getenv | call to getenv |

View File

@@ -9,6 +9,5 @@ nodes
| test.cpp:20:29:20:47 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:24:10:24:35 | ! ... | semmle.label | ! ... |
| test.cpp:24:11:24:16 | call to strcmp | semmle.label | call to strcmp |
| test.cpp:24:11:24:16 | call to strcmp | semmle.label | call to strcmp |
#select
| test.cpp:24:10:24:35 | ! ... | test.cpp:20:29:20:34 | call to getenv | test.cpp:24:10:24:35 | ! ... | Reliance on untrusted input $@ to raise privilege at $@. | test.cpp:20:29:20:34 | call to getenv | call to getenv | test.cpp:25:9:25:27 | ... = ... | ... = ... |

View File

@@ -0,0 +1,3 @@
| test.cpp:5:7:5:12 | Class2 | AV Rule 76: A copy constructor and an assignment operator shall be declared for classes that contain pointers to data items or nontrivial destructors. |
| test.cpp:16:7:16:12 | Class3 | AV Rule 76: A copy constructor and an assignment operator shall be declared for classes that contain pointers to data items or nontrivial destructors. |
| test.cpp:33:7:33:12 | Class4 | AV Rule 76: A copy constructor and an assignment operator shall be declared for classes that contain pointers to data items or nontrivial destructors. |

View File

@@ -0,0 +1 @@
jsf/4.10 Classes/AV Rule 76.ql

View File

@@ -0,0 +1,96 @@
class Class1 // good: no pointer members, default assignment operator and copy constructor
{
};
class Class2 // bad: pointer members, default assignment operator and copy constructor
{
private:
int* _a;
public:
Class2(int* a):_a(a)
{
}
};
class Class3 // bad: pointer members, custom assignment operator and default copy constructor
{
private:
int* _a;
public:
Class3(int* a) :_a(a)
{
}
Class3& operator=(const Class3& rhs)
{
this->_a = rhs._a;
return *this;
}
};
class Class4 // bad: pointer members, default assignment operator and custom copy constructor
{
private:
int* _a;
public:
Class4(int* a) :_a(a)
{
}
Class4(const Class4& rhs):_a(rhs._a)
{
}
};
class Class5 // good: pointer members, custom assignment operator and copy constructor
{
private:
int* _a;
public:
Class5(int* a) :_a(a)
{
}
Class5(const Class5& rhs) :_a(rhs._a)
{
}
Class5& operator=(const Class5& rhs)
{
this->_a = rhs._a;
return *this;
}
};
class Class6 // good: pointer members, deleted assignment operator and copy constructor
{
private:
int* _a;
public:
Class6(int* a) :_a(a)
{
}
Class6& operator=(const Class6& rhs) = delete;
Class6(const Class6& rhs) = delete;
};
class Class7 // good: pointer members, disallowed assignment operator and copy constructor
{
private:
int* _a;
public:
Class7(int* a) :_a(a)
{
}
private:
Class7& operator=(const Class7& rhs); // no implementation to get linker error!
Class7(const Class7& rhs); // no implementation to get linker error!
};

View File

@@ -1,3 +1,7 @@
## 1.3.3
No user-facing changes.
## 1.3.2
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.3.3
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.3.2
lastReleaseVersion: 1.3.3

View File

@@ -1,8 +1,8 @@
name: codeql/csharp-solorigate-all
version: 1.3.3-dev
version: 1.3.3
groups:
- csharp
- solorigate
library: true
dependencies:
codeql/csharp-all: "*"
codeql/csharp-all: ${workspace}

View File

@@ -1,3 +1,7 @@
## 1.3.3
No user-facing changes.
## 1.3.2
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 1.3.3
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.3.2
lastReleaseVersion: 1.3.3

View File

@@ -1,9 +1,9 @@
name: codeql/csharp-solorigate-queries
version: 1.3.3-dev
version: 1.3.3
groups:
- csharp
- solorigate
defaultSuiteFile: codeql-suites/solorigate.qls
dependencies:
codeql/csharp-all: "*"
codeql/csharp-solorigate-all: "*"
codeql/csharp-all: ${workspace}
codeql/csharp-solorigate-all: ${workspace}

View File

@@ -4,9 +4,9 @@ groups:
- solorigate
- test
dependencies:
codeql/csharp-all: "*"
codeql/csharp-queries: "*"
codeql/csharp-solorigate-all: "*"
codeql/csharp-solorigate-queries: "*"
codeql/csharp-all: ${workspace}
codeql/csharp-queries: ${workspace}
codeql/csharp-solorigate-all: ${workspace}
codeql/csharp-solorigate-queries: ${workspace}
extractor: csharp
tests: .

View File

@@ -1,5 +1,5 @@
name: codeql-csharp-consistency-queries
groups: [csharp, test, consistency-queries]
dependencies:
codeql/csharp-all: "*"
codeql/csharp-all: ${workspace}
extractor: csharp

View File

@@ -3,4 +3,4 @@ groups:
- csharp
- examples
dependencies:
codeql/csharp-all: "*"
codeql/csharp-all: ${workspace}

View File

@@ -1,3 +1,7 @@
## 0.4.3
No user-facing changes.
## 0.4.2
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 0.4.3
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.2
lastReleaseVersion: 0.4.3

View File

@@ -1,9 +1,9 @@
name: codeql/csharp-all
version: 0.4.3-dev
version: 0.4.3
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp
library: true
upgrades: upgrades
dependencies:
codeql/ssa: 0.0.1
codeql/ssa: ${workspace}

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -2874,54 +2874,16 @@ private class AccessPathCons1 extends AccessPath, TAccessPathCons1 {
}
}
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source are generated.
*/
class PathNode extends TPathNode {
/** Gets a textual representation of this element. */
string toString() { none() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { none() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
none()
}
/** Gets the underlying `Node`. */
final Node getNode() { this.(PathNodeImpl).getNodeEx().projectToNode() = result }
abstract private class PathNodeImpl extends TPathNode {
/** Gets the `FlowState` of this node. */
FlowState getState() { none() }
abstract FlowState getState();
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getANonHiddenSuccessor() and
reach(this) and
reach(result)
}
abstract Configuration getConfiguration();
/** Holds if this node is a source. */
predicate isSource() { none() }
}
abstract predicate isSource();
abstract private class PathNodeImpl extends PathNode {
abstract PathNodeImpl getASuccessorImpl();
private PathNodeImpl getASuccessorIfHidden() {
@@ -2967,13 +2929,23 @@ abstract private class PathNodeImpl extends PathNode {
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
}
override string toString() { result = this.getNodeEx().toString() + this.ppAp() }
/** Gets a textual representation of this element. */
string toString() { result = this.getNodeEx().toString() + this.ppAp() }
override string toStringWithContext() {
result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx()
}
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
string toStringWithContext() { result = this.getNodeEx().toString() + this.ppAp() + this.ppCtx() }
override predicate hasLocationInfo(
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getNodeEx().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
@@ -2986,14 +2958,59 @@ private predicate directReach(PathNodeImpl n) {
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
private predicate reach(PathNodeImpl n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNodeImpl n1, PathNode n2) {
private predicate pathSucc(PathNodeImpl n1, PathNodeImpl n2) {
n1.getANonHiddenSuccessor() = n2 and directReach(n2)
}
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
*/
class PathNode instanceof PathNodeImpl {
PathNode() { reach(this) }
/** Gets a textual representation of this element. */
final string toString() { result = super.toString() }
/**
* Gets a textual representation of this element, including a textual
* representation of the call context.
*/
final string toStringWithContext() { result = super.toStringWithContext() }
/**
* Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to
* column `endcolumn` of line `endline` in file `filepath`.
* For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/
final predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets the underlying `Node`. */
final Node getNode() { super.getNodeEx().projectToNode() = result }
/** Gets the `FlowState` of this node. */
final FlowState getState() { result = super.getState() }
/** Gets the associated configuration. */
final Configuration getConfiguration() { result = super.getConfiguration() }
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() { result = super.getANonHiddenSuccessor() }
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
}
/**
* Provides the query predicates needed to include a graph in a path-problem query.
@@ -3004,7 +3021,7 @@ module PathGraph {
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
key = "semmle.label" and val = n.toString()
}
/**
@@ -3013,11 +3030,7 @@ module PathGraph {
* `ret -> out` is summarized as the edge `arg -> out`.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
Subpaths::subpaths(arg, par, ret, out) and
reach(arg) and
reach(par) and
reach(ret) and
reach(out)
Subpaths::subpaths(arg, par, ret, out)
}
}
@@ -3399,7 +3412,7 @@ private module Subpaths {
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, FlowState sout, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3407,14 +3420,14 @@ private module Subpaths {
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
private Configuration getPathNodeConf(PathNodeImpl n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
PathNodeImpl arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, FlowState sout, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, sout, apout) and
@@ -3444,7 +3457,7 @@ private module Subpaths {
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) {
predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNodeImpl out) {
exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 |
pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and
subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and
@@ -3460,7 +3473,7 @@ private module Subpaths {
* Holds if `n` can reach a return node in a summarized subpath that can reach a sink.
*/
predicate retReach(PathNodeImpl n) {
exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
exists(PathNodeImpl out | subpaths(_, _, n, out) | directReach(out) or retReach(out))
or
exists(PathNodeImpl mid |
retReach(mid) and
@@ -3477,11 +3490,12 @@ private module Subpaths {
* sinks.
*/
private predicate flowsTo(
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration
) {
flowsource.isSource() and
flowsource.getConfiguration() = configuration and
flowsource.(PathNodeImpl).getNodeEx().asNode() = source and
flowsource.getNodeEx().asNode() = source and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.getNodeEx().asNode() = sink
}
@@ -3504,14 +3518,14 @@ private predicate finalStats(
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0)) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap)) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state)) and
tuples = count(PathNode pn)
tuples = count(PathNodeImpl pn)
or
fwd = false and
nodes = count(NodeEx n0 | exists(PathNodeImpl pn | pn.getNodeEx() = n0 and reach(pn))) and
fields = count(TypedContent f0 | exists(PathNodeMid pn | pn.getAp().getHead() = f0 and reach(pn))) and
conscand = count(AccessPath ap | exists(PathNodeMid pn | pn.getAp() = ap and reach(pn))) and
states = count(FlowState state | exists(PathNodeMid pn | pn.getState() = state and reach(pn))) and
tuples = count(PathNode pn | reach(pn))
tuples = count(PathNode pn)
}
/**

View File

@@ -310,12 +310,27 @@ module LocalFlow {
* Holds if `nodeFrom` is a last node referencing SSA definition `def`, which
* can reach `next`.
*/
private predicate localFlowSsaInput(Node nodeFrom, Ssa::Definition def, Ssa::Definition next) {
exists(ControlFlow::BasicBlock bb, int i | SsaImpl::lastRefBeforeRedef(def, bb, i, next) |
private predicate localFlowSsaInputFromDef(
Node nodeFrom, Ssa::Definition def, Ssa::Definition next
) {
exists(ControlFlow::BasicBlock bb, int i |
SsaImpl::lastRefBeforeRedef(def, bb, i, next) and
def.definesAt(_, bb, i) and
def = getSsaDefinition(nodeFrom)
or
nodeFrom.asExprAtNode(bb.getNode(i)) instanceof AssignableRead
)
}
/**
* Holds if `read` is a last node reading SSA definition `def`, which
* can reach `next`.
*/
predicate localFlowSsaInputFromExpr(
ControlFlow::Node read, Ssa::Definition def, Ssa::Definition next
) {
exists(ControlFlow::BasicBlock bb, int i |
SsaImpl::lastRefBeforeRedef(def, bb, i, next) and
read = bb.getNode(i) and
read.getElement() instanceof AssignableRead
)
}
@@ -351,18 +366,14 @@ module LocalFlow {
// Flow from read to next read
localSsaFlowStepUseUse(def, nodeFrom.(PostUpdateNode).getPreUpdateNode(), nodeTo)
or
// Flow into phi node
exists(Ssa::PhiNode phi |
localFlowSsaInput(nodeFrom, def, phi) and
phi = nodeTo.(SsaDefinitionNode).getDefinition() and
def = phi.getAnInput()
)
or
// Flow into uncertain SSA definition
exists(LocalFlow::UncertainExplicitSsaDefinition uncertain |
localFlowSsaInput(nodeFrom, def, uncertain) and
uncertain = nodeTo.(SsaDefinitionNode).getDefinition() and
def = uncertain.getPriorDefinition()
// Flow into phi/uncertain SSA definition node from def
exists(Ssa::Definition next |
localFlowSsaInputFromDef(nodeFrom, def, next) and
next = nodeTo.(SsaDefinitionNode).getDefinition()
|
def = next.(Ssa::PhiNode).getAnInput()
or
def = next.(LocalFlow::UncertainExplicitSsaDefinition).getPriorDefinition()
)
}
@@ -519,11 +530,26 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
or
exists(Ssa::Definition def |
LocalFlow::localSsaFlowStepUseUse(def, nodeFrom, nodeTo) and
not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom,
any(DataFlowSummarizedCallable sc)) and
not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _) and
not LocalFlow::usesInstanceField(def)
)
or
// Flow into phi/uncertain SSA definition node from read
exists(Ssa::Definition def, ControlFlow::Node read, Ssa::Definition next |
LocalFlow::localFlowSsaInputFromExpr(read, def, next) and
next = nodeTo.(SsaDefinitionNode).getDefinition() and
def =
[
next.(Ssa::PhiNode).getAnInput(),
next.(LocalFlow::UncertainExplicitSsaDefinition).getPriorDefinition()
]
|
exists(nodeFrom.asExprAtNode(read)) and
not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _)
or
exists(nodeFrom.(PostUpdateNode).getPreUpdateNode().asExprAtNode(read))
)
or
LocalFlow::localFlowCapturedVarStep(nodeFrom, nodeTo)
or
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true)
@@ -859,6 +885,21 @@ private module Cached {
LocalFlow::usesInstanceField(def)
)
or
// Flow into phi/uncertain SSA definition node from read
exists(Ssa::Definition def, ControlFlow::Node read, Ssa::Definition next |
LocalFlow::localFlowSsaInputFromExpr(read, def, next) and
next = nodeTo.(SsaDefinitionNode).getDefinition() and
def =
[
next.(Ssa::PhiNode).getAnInput(),
next.(LocalFlow::UncertainExplicitSsaDefinition).getPriorDefinition()
]
|
exists(nodeFrom.asExprAtNode(read))
or
exists(nodeFrom.(PostUpdateNode).getPreUpdateNode().asExprAtNode(read))
)
or
// Simple flow through library code is included in the exposed local
// step relation, even though flow is technically inter-procedural
FlowSummaryImpl::Private::Steps::summaryThroughStepValue(nodeFrom, nodeTo,

View File

@@ -1067,6 +1067,59 @@ private predicate variableReadPseudo(ControlFlow::BasicBlock bb, int i, Ssa::Sou
capturedReadIn(bb, i, v, _, _, _)
}
pragma[noinline]
private predicate adjacentDefRead(
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2,
SsaInput::SourceVariable v
) {
adjacentDefRead(def, bb1, i1, bb2, i2) and
v = def.getSourceVariable()
}
private predicate adjacentDefReachesRead(
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
) {
exists(SsaInput::SourceVariable v | adjacentDefRead(def, bb1, i1, bb2, i2, v) |
def.definesAt(v, bb1, i1)
or
SsaInput::variableRead(bb1, i1, v, true)
)
or
exists(SsaInput::BasicBlock bb3, int i3 |
adjacentDefReachesRead(def, bb1, i1, bb3, i3) and
SsaInput::variableRead(bb3, i3, _, false) and
adjacentDefRead(def, bb3, i3, bb2, i2)
)
}
/** Same as `adjacentDefRead`, but skips uncertain reads. */
pragma[nomagic]
private predicate adjacentDefSkipUncertainReads(
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
) {
adjacentDefReachesRead(def, bb1, i1, bb2, i2) and
SsaInput::variableRead(bb2, i2, _, true)
}
private predicate adjacentDefReachesUncertainRead(
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
) {
adjacentDefReachesRead(def, bb1, i1, bb2, i2) and
SsaInput::variableRead(bb2, i2, _, false)
}
/** Same as `lastRefRedef`, but skips uncertain reads. */
pragma[nomagic]
private predicate lastRefSkipUncertainReads(Definition def, SsaInput::BasicBlock bb, int i) {
lastRef(def, bb, i) and
not SsaInput::variableRead(bb, i, def.getSourceVariable(), false)
or
exists(SsaInput::BasicBlock bb0, int i0 |
lastRef(def, bb0, i0) and
adjacentDefReachesUncertainRead(def, bb, i, bb0, i0)
)
}
cached
private module Cached {
cached
@@ -1237,7 +1290,7 @@ private module Cached {
predicate firstReadSameVar(Definition def, ControlFlow::Node cfn) {
exists(ControlFlow::BasicBlock bb1, int i1, ControlFlow::BasicBlock bb2, int i2 |
def.definesAt(_, bb1, i1) and
adjacentDefNoUncertainReads(def, bb1, i1, bb2, i2) and
adjacentDefSkipUncertainReads(def, bb1, i1, bb2, i2) and
cfn = bb2.getNode(i2)
)
}
@@ -1252,20 +1305,27 @@ private module Cached {
exists(ControlFlow::BasicBlock bb1, int i1, ControlFlow::BasicBlock bb2, int i2 |
cfn1 = bb1.getNode(i1) and
variableReadActual(bb1, i1, _) and
adjacentDefNoUncertainReads(def, bb1, i1, bb2, i2) and
adjacentDefSkipUncertainReads(def, bb1, i1, bb2, i2) and
cfn2 = bb2.getNode(i2)
)
}
/** Same as `lastRefRedef`, but skips uncertain reads. */
cached
predicate lastRefBeforeRedef(Definition def, ControlFlow::BasicBlock bb, int i, Definition next) {
lastRefRedefNoUncertainReads(def, bb, i, next)
lastRefRedef(def, bb, i, next) and
not SsaInput::variableRead(bb, i, def.getSourceVariable(), false)
or
exists(SsaInput::BasicBlock bb0, int i0 |
lastRefRedef(def, bb0, i0, next) and
adjacentDefReachesUncertainRead(def, bb, i, bb0, i0)
)
}
cached
predicate lastReadSameVar(Definition def, ControlFlow::Node cfn) {
exists(ControlFlow::BasicBlock bb, int i |
lastRefNoUncertainReads(def, bb, i) and
lastRefSkipUncertainReads(def, bb, i) and
variableReadActual(bb, i, _) and
cfn = bb.getNode(i)
)

View File

@@ -1,3 +1,7 @@
## 0.4.3
No user-facing changes.
## 0.4.2
No user-facing changes.

View File

@@ -1,6 +1,6 @@
/**
* @id cs/summary/lines-of-code
* @name Total lines of code in the database
* @name Total lines of C# code in the database
* @description The total number of lines of code across all files. This is a useful metric of the size of a database. For all files that were seen during the build, this query counts the lines of code, excluding whitespace or comments.
* @kind metric
* @tags summary

View File

@@ -0,0 +1,3 @@
## 0.4.3
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.2
lastReleaseVersion: 0.4.3

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-queries
version: 0.4.3-dev
version: 0.4.3
groups:
- csharp
- queries
@@ -7,5 +7,5 @@ suites: codeql-suites
extractor: csharp
defaultSuiteFile: codeql-suites/csharp-code-scanning.qls
dependencies:
codeql/csharp-all: "*"
codeql/suite-helpers: "*"
codeql/csharp-all: ${workspace}
codeql/suite-helpers: ${workspace}

View File

@@ -1 +1 @@
| test.cs:31:9:31:74 | call to method InitiateSystemShutdownExW | Call to an external method 'InitiateSystemShutdownExW'. |
| test.cs:32:9:32:74 | call to method InitiateSystemShutdownExW | Call to an external method 'InitiateSystemShutdownExW'. |

View File

@@ -1,23 +1,17 @@
edges
| test.cs:68:34:68:76 | call to method GetLastWriteTime : DateTime | test.cs:70:36:70:48 | access to local variable lastWriteTime |
| test.cs:70:13:70:71 | call to method CompareTo : Int32 | test.cs:70:13:70:76 | ... >= ... |
| test.cs:70:36:70:48 | access to local variable lastWriteTime | test.cs:70:36:70:70 | call to method AddHours |
| test.cs:70:36:70:48 | access to local variable lastWriteTime | test.cs:70:36:70:70 | call to method AddHours : DateTime |
| test.cs:70:36:70:48 | access to local variable lastWriteTime : DateTime | test.cs:70:36:70:70 | call to method AddHours |
| test.cs:70:36:70:48 | access to local variable lastWriteTime : DateTime | test.cs:70:36:70:70 | call to method AddHours : DateTime |
| test.cs:70:36:70:70 | call to method AddHours | test.cs:70:13:70:71 | call to method CompareTo |
| test.cs:70:36:70:70 | call to method AddHours | test.cs:70:13:70:71 | call to method CompareTo : Int32 |
| test.cs:70:36:70:70 | call to method AddHours : DateTime | test.cs:70:13:70:71 | call to method CompareTo |
| test.cs:70:36:70:70 | call to method AddHours : DateTime | test.cs:70:13:70:71 | call to method CompareTo : Int32 |
| test.cs:69:34:69:76 | call to method GetLastWriteTime : DateTime | test.cs:71:36:71:48 | access to local variable lastWriteTime |
| test.cs:71:13:71:71 | call to method CompareTo : Int32 | test.cs:71:13:71:76 | ... >= ... |
| test.cs:71:36:71:48 | access to local variable lastWriteTime | test.cs:71:36:71:70 | call to method AddHours |
| test.cs:71:36:71:70 | call to method AddHours | test.cs:71:13:71:71 | call to method CompareTo |
| test.cs:71:36:71:70 | call to method AddHours | test.cs:71:13:71:71 | call to method CompareTo : Int32 |
#select
| test.cs:70:9:73:9 | if (...) ... | test.cs:68:34:68:76 | call to method GetLastWriteTime : DateTime | test.cs:70:13:70:71 | call to method CompareTo | Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger. | test.cs:70:13:70:71 | call to method CompareTo | call to method CompareTo | test.cs:70:36:70:70 | call to method AddHours | offset | test.cs:68:34:68:76 | call to method GetLastWriteTime | last modification time of a file |
| test.cs:70:9:73:9 | if (...) ... | test.cs:68:34:68:76 | call to method GetLastWriteTime : DateTime | test.cs:70:13:70:71 | call to method CompareTo : Int32 | Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger. | test.cs:70:13:70:71 | call to method CompareTo | call to method CompareTo | test.cs:70:36:70:70 | call to method AddHours | offset | test.cs:68:34:68:76 | call to method GetLastWriteTime | last modification time of a file |
| test.cs:70:9:73:9 | if (...) ... | test.cs:68:34:68:76 | call to method GetLastWriteTime : DateTime | test.cs:70:13:70:76 | ... >= ... | Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger. | test.cs:70:13:70:71 | call to method CompareTo | call to method CompareTo | test.cs:70:36:70:70 | call to method AddHours | offset | test.cs:68:34:68:76 | call to method GetLastWriteTime | last modification time of a file |
| test.cs:70:9:73:9 | if (...) ... | test.cs:68:34:68:76 | call to method GetLastWriteTime : DateTime | test.cs:70:13:70:76 | ... >= ... : Boolean | Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger. | test.cs:70:13:70:71 | call to method CompareTo | call to method CompareTo | test.cs:70:36:70:70 | call to method AddHours | offset | test.cs:68:34:68:76 | call to method GetLastWriteTime | last modification time of a file |
| test.cs:71:9:74:9 | if (...) ... | test.cs:69:34:69:76 | call to method GetLastWriteTime : DateTime | test.cs:71:13:71:71 | call to method CompareTo | Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger. | test.cs:71:13:71:71 | call to method CompareTo | call to method CompareTo | test.cs:71:36:71:70 | call to method AddHours | offset | test.cs:69:34:69:76 | call to method GetLastWriteTime | last modification time of a file |
| test.cs:71:9:74:9 | if (...) ... | test.cs:69:34:69:76 | call to method GetLastWriteTime : DateTime | test.cs:71:13:71:71 | call to method CompareTo : Int32 | Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger. | test.cs:71:13:71:71 | call to method CompareTo | call to method CompareTo | test.cs:71:36:71:70 | call to method AddHours | offset | test.cs:69:34:69:76 | call to method GetLastWriteTime | last modification time of a file |
| test.cs:71:9:74:9 | if (...) ... | test.cs:69:34:69:76 | call to method GetLastWriteTime : DateTime | test.cs:71:13:71:76 | ... >= ... | Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger. | test.cs:71:13:71:71 | call to method CompareTo | call to method CompareTo | test.cs:71:36:71:70 | call to method AddHours | offset | test.cs:69:34:69:76 | call to method GetLastWriteTime | last modification time of a file |
nodes
| test.cs:68:34:68:76 | call to method GetLastWriteTime : DateTime | semmle.label | call to method GetLastWriteTime : DateTime |
| test.cs:70:13:70:71 | call to method CompareTo | semmle.label | call to method CompareTo |
| test.cs:70:13:70:71 | call to method CompareTo : Int32 | semmle.label | call to method CompareTo : Int32 |
| test.cs:70:13:70:76 | ... >= ... | semmle.label | ... >= ... |
| test.cs:70:36:70:48 | access to local variable lastWriteTime | semmle.label | access to local variable lastWriteTime |
| test.cs:70:36:70:70 | call to method AddHours | semmle.label | call to method AddHours |
| test.cs:69:34:69:76 | call to method GetLastWriteTime : DateTime | semmle.label | call to method GetLastWriteTime : DateTime |
| test.cs:71:13:71:71 | call to method CompareTo | semmle.label | call to method CompareTo |
| test.cs:71:13:71:71 | call to method CompareTo : Int32 | semmle.label | call to method CompareTo : Int32 |
| test.cs:71:13:71:76 | ... >= ... | semmle.label | ... >= ... |
| test.cs:71:36:71:48 | access to local variable lastWriteTime | semmle.label | access to local variable lastWriteTime |
| test.cs:71:36:71:70 | call to method AddHours | semmle.label | call to method AddHours |

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