Compare commits

..

1255 Commits

Author SHA1 Message Date
Ian Wright
a716d39370 repatch 2021-12-17 16:59:31 +00:00
Ian Wright
335b2466a9 patch again 2021-12-17 16:49:40 +00:00
Ian Wright
96ae9617ec post cherry-pick patch 2021-12-17 16:43:07 +00:00
Henry Mercer
82029663b2 JS: Push FeaturizationConfig context into more predicates 2021-12-17 16:03:15 +00:00
Henry Mercer
4cd15ba654 JS: Only featurize endpoints that are part of a flow path 2021-12-17 15:58:46 +00:00
Ian Wright
c17c10e450 Revert "JS: Push FeaturizationConfig context into more predicates"
This reverts commit a0f479d503.
2021-12-17 15:54:03 +00:00
Henry Mercer
a0f479d503 JS: Push FeaturizationConfig context into more predicates 2021-12-17 13:54:25 +00:00
Ian Wright
24a5e8a8e1 bump the release number 2021-12-17 13:12:05 +00:00
Henry Mercer
427cdf480a JS: Update featurization for absent features optimization
Absent features are now represented implicitly by the absence of a row
in the `tokenFeatures` relation, rather than explicitly by an empty
string. This leads to improved runtime performance. To enable this
implicit representation, we pass the set of supported token features to
the `scoreEndpoints` HOP. Requires CodeQL CLI v2.7.4.
2021-12-17 13:10:10 +00:00
Ian Wright
8e1f2645cb bump the release number 2021-12-17 13:10:10 +00:00
CodeQL CI
39ec7132af Merge pull request #7049 from asgerf/js/routing-trees
Approved by erik-krogh
2021-12-17 12:26:38 +00:00
Tony Torralba
f3819e7b06 Merge pull request #7435 from github/atorralba/log4j-CVE-2021-45046
Java: New sinks for Log4j CloseableThreadContext
2021-12-17 13:19:51 +01:00
Erik Krogh Kristensen
c70a2bebda Merge pull request #7410 from erik-krogh/erik-krogh/publish-ql-for-ql
Add QL for QL
2021-12-17 12:55:25 +01:00
Anders Schack-Mulligen
3adc0b57ed Merge pull request #7426 from MathiasVP/fix-join-order-in-http-string-literal-charpred
C++: Fix join-order in `HttpStringLiteral` charpred
2021-12-17 11:21:38 +01:00
Arthur Baars
96aef9f63f Merge pull request #7393 from aibaars/ruby-simple-parameter-not-expr
Ruby: SimpleParameter should not be an Expr
2021-12-17 10:41:43 +01:00
Tom Hvitved
734bfbd7ae Merge pull request #7433 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-12-17 09:52:36 +01:00
Tony Torralba
6f2d91a8ad Sinks for CloseableThreadContext 2021-12-17 09:17:04 +01:00
github-actions[bot]
6c57cbba2b Add changed framework coverage reports 2021-12-17 00:09:41 +00:00
Erik Krogh Kristensen
2626b0b3dc QL: fix test workflow 2021-12-16 22:26:42 +01:00
Erik Krogh Kristensen
be076dc2c8 add Erik and Taus as QL-for-QL reviewers 2021-12-16 21:47:42 +01:00
Mathias Vorreiter Pedersen
53a1f935b7 C++: Fix join-order in 'HttpStringLiteral' charpred. 2021-12-16 17:12:50 +00:00
Chris Gavin
8fabbd697e Merge pull request #7422 from github/todo-comment-kind
Add `kind` metadata to example query.
2021-12-16 16:36:15 +00:00
Chris Smowton
e3b2eed2d2 Merge pull request #7423 from github/atorralba/log4j-CVE-2021-45046
Java: Cover CVE-2021-45046 in the Log4jJndiInjection query
2021-12-16 16:00:45 +00:00
Erik Krogh Kristensen
8eda061d2f add dbscheme and codeql version to query hash 2021-12-16 15:49:07 +01:00
Tom Hvitved
579b58b8fa Merge pull request #7402 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-12-16 15:42:10 +01:00
Arthur Baars
3ef707e358 Address comment 2021-12-16 15:38:41 +01:00
Arthur Baars
cdbd8b27d3 Ruby: SimpleParameter is not an Expr 2021-12-16 15:38:40 +01:00
Chris Gavin
4a1e2ed408 Add a severity and select the correct number of columns. 2021-12-16 14:02:36 +00:00
Tom Hvitved
e9ef53c31b Merge pull request #7390 from hvitved/ruby/deprecate-pattern-classes
Ruby: Deprecate `Pattern` classes
2021-12-16 14:36:13 +01:00
Tony Torralba
7d6cba77a0 Add tests 2021-12-16 13:44:01 +01:00
Tony Torralba
2e0ca6ce2b Add stubs 2021-12-16 13:44:01 +01:00
Tony Torralba
7d70b77141 Add new sinks and taint steps 2021-12-16 13:43:58 +01:00
Chris Gavin
407c265daf Add kind metadata to example query. 2021-12-16 12:12:36 +00:00
Michael Nebel
95d175e9e0 Merge pull request #7406 from michaelnebel/csharp-system-threading-csv
C#: Convert more flow summaries to CSV format.
2021-12-16 12:56:44 +01:00
Michael Nebel
d777ba8a25 C#: Cleanup private imports in LibraryTypeDataFlow. 2021-12-16 11:24:24 +01:00
Michael Nebel
a26403b359 Convert System.Tuple and friends flow to CSV format. 2021-12-16 11:20:04 +01:00
Asger Feldthaus
0e9c2377e3 JS: Use a field in RouterHandlerParameter 2021-12-16 10:26:35 +01:00
Michael Nebel
348e3b74f3 C#: Convert System.Text.Encoding flow to CSV format. 2021-12-16 10:03:12 +01:00
CodeQL CI
f274f06d9b Merge pull request #7409 from asgerf/js/track-functions-with-methods
Approved by erik-krogh
2021-12-16 09:01:42 +00:00
CodeQL CI
acbf7913b2 Merge pull request #7408 from asgerf/js/trusted-types-sinks
Approved by esbena
2021-12-16 08:59:51 +00:00
Michael Nebel
a5c055581e C#: Convert System.Runtime.CompilerServices.ConfiguredTaskAwaitable<>.ConfiguredTaskAwaiter flow to CSV format. 2021-12-16 09:36:39 +01:00
Michael Nebel
ddb7d722bc C#: Convert System.Runtime.CompilerServices.TaskAwaiter<> flow to CSV format. 2021-12-16 09:36:39 +01:00
Michael Nebel
bdd44c1c46 C#: Convert System.Runtime.CompilerServices.ConfiguredTaskAwaitable flow to CSV format. 2021-12-16 09:36:39 +01:00
Michael Nebel
034d45ddc0 C#: Convert System.Threading.Tasks.TaskFactory flow to CSV format. 2021-12-16 09:36:39 +01:00
Michael Nebel
440976fe63 C#: Convert System.Threading.Tasks.Task<> flow to CSV format. 2021-12-16 09:36:39 +01:00
Michael Nebel
cde98c7799 C#: Convert System.Threading.Tasks.Task flow to CSV format. 2021-12-16 09:36:39 +01:00
Michael Nebel
90d7b94b8a Merge pull request #7413 from hvitved/csharp/fix-test
C#: Fix broken `FlowSummariesFiltered` test
2021-12-16 09:31:33 +01:00
github-actions[bot]
18489c0ded Add changed framework coverage reports 2021-12-16 00:09:34 +00:00
Tom Hvitved
4ccf9bf67c Address review comments 2021-12-15 19:57:27 +01:00
Tom Hvitved
8f1b2b3bb5 C#: Fix broken FlowSummariesFiltered test 2021-12-15 18:32:25 +01:00
Arthur Baars
b53e3499cb Merge pull request #7249 from ShockwaveNN/patch-1
Fix ruby incorrect version in documentation
2021-12-15 18:32:24 +01:00
Asger Feldthaus
53b3581ed0 JS: Add test to stress flow through properties 2021-12-15 17:16:56 +01:00
Asger F
784991cce5 Update javascript/ql/lib/semmle/javascript/Routing.qll
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2021-12-15 16:38:38 +01:00
Asger Feldthaus
79e6dcaf68 JS: Rename getValueAtAccessPath->getValueImplicitlyStoredInAccessPath 2021-12-15 16:37:28 +01:00
Asger Feldthaus
8aa4d8227e JS: Rename RouteHandlerInput->RouteHandlerParameter 2021-12-15 16:32:18 +01:00
Tom Hvitved
3bc6247ad8 Merge pull request #7378 from hvitved/ruby/module-infinite-loop
Ruby: Prevent infinite recursion in module resolution library
2021-12-15 16:27:36 +01:00
Asger Feldthaus
218b746f6f JS: Rename getAUseSite -> getRouteInstallation 2021-12-15 16:21:41 +01:00
Asger Feldthaus
4d85799fc7 JS: Add test for fastify-rate-limit 2021-12-15 16:18:22 +01:00
Asger Feldthaus
615b2ec539 JS: Fix handling of fastify-plugin 2021-12-15 16:04:46 +01:00
Asger Feldthaus
b226f767ad JS: Fix tracking of fastify server instance 2021-12-15 16:04:45 +01:00
Asger Feldthaus
0ca9feb854 JS: Always treat routers as resuming dispatch 2021-12-15 16:01:59 +01:00
Asger F
1b20506947 Update javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2021-12-15 16:00:19 +01:00
Asger Feldthaus
995e33158f JS: Add test for res.locals flow to template 2021-12-15 16:00:19 +01:00
Asger Feldthaus
04bdba85ea JS: Shift line numbers in test expectations 2021-12-15 16:00:19 +01:00
Asger F
c1bb40f439 Update javascript/ql/lib/semmle/javascript/frameworks/Express.qll
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2021-12-15 16:00:19 +01:00
Asger Feldthaus
b2016bddac JS: Merge concepts of client/database in MongoDB model 2021-12-15 16:00:19 +01:00
Tom Hvitved
c6696adfde Ruby: Add test case that would make old module resolution library diverge 2021-12-15 15:18:42 +01:00
Tom Hvitved
2187994f5c Ruby: Prevent infinite recursion in module resolution library 2021-12-15 15:15:19 +01:00
Arthur Baars
7ddfc00655 Merge branch 'main' into patch-1 2021-12-15 14:52:35 +01:00
Tony Torralba
7e644d8d7b Merge pull request #6098 from atorralba/atorralba/entrypoint-field-steps
Java: Preserve taint on field-read-steps on entrypoint types
2021-12-15 14:51:38 +01:00
Erik Krogh Kristensen
76dcfd479e more specific search path for dataset measure job 2021-12-15 14:36:43 +01:00
Erik Krogh Kristensen
133c496b94 Merge branch 'main' into erik-krogh/publish-ql-for-ql 2021-12-15 14:34:04 +01:00
Erik Krogh Kristensen
4beaceec68 QL: fix Buildins/Builtins typo 2021-12-15 14:26:58 +01:00
Erik Krogh Kristensen
fb979231f3 QL: merge the .codeqlmanifest.json file in the root 2021-12-15 14:22:40 +01:00
Erik Krogh Kristensen
0ac3e5c3ad Merge QL for QL into github/codeql 2021-12-15 14:19:53 +01:00
Erik Krogh Kristensen
8d91ba2a6e QL: fix Esbens workflow comments 2021-12-15 14:07:36 +01:00
Erik Krogh Kristensen
77cb822907 QL: fix search path for dataset measure 2021-12-15 13:34:33 +01:00
Tony Torralba
c1e4c05aa2 Update change note to new format 2021-12-15 13:08:34 +01:00
Tony Torralba
e2022f467c Update java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2021-12-15 13:00:16 +01:00
Tony Torralba
a3b25f0eb5 Don't consider subtypes of fields 2021-12-15 13:00:16 +01:00
Tony Torralba
47002a3bd7 Fix test 2021-12-15 13:00:16 +01:00
Tony Torralba
1426c5b406 Consider parameterized types 2021-12-15 13:00:16 +01:00
Tony Torralba
7ce9b04941 Add change note 2021-12-15 13:00:15 +01:00
Tony Torralba
5e80044f11 Preserve taint on field-read-steps on entrypoint types 2021-12-15 13:00:15 +01:00
Asger Feldthaus
e64a6dc12a JS: Add qldoc 2021-12-15 12:47:23 +01:00
Erik Krogh Kristensen
faaa74b1cd QL: move .git files into the ql/ folder 2021-12-15 12:25:08 +01:00
Erik Krogh Kristensen
24c2578540 QL: cache query compilation 2021-12-15 12:25:08 +01:00
Erik Krogh Kristensen
5d93309ada QL: call the product QL for QL (because it rolls nicely).
and update the readme.
2021-12-15 12:25:06 +01:00
Erik Krogh Kristensen
d89c41bae4 QL: update the readme 2021-12-15 12:24:51 +01:00
Asger Feldthaus
43ec721a87 JS: Add link to MDN docs for trusted types 2021-12-15 11:52:58 +01:00
Geoffrey White
9363d64166 Merge pull request #7395 from MathiasVP/fix-fp-in-pointless-self-comparison
C++: Fix FP in `cpp/comparison-of-identical-expressions`
2021-12-15 10:47:57 +00:00
Mathias Vorreiter Pedersen
65c301c39f Update cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/templates.cpp
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2021-12-15 09:22:41 +00:00
Michael Nebel
0e7fdbeeab Merge pull request #7384 from michaelnebel/csharp-mad-xml
C#: Convert XML related flow summaries to CSV and fix flow summaries test cases.
2021-12-15 09:51:20 +01:00
Harry Maclean
062f7fe390 Merge pull request #7340 from github/hmac/private-methods
Ruby: handle private module methods
2021-12-15 21:07:49 +13:00
Harry Maclean
a32711245f Ruby: Further speed up private method modelling 2021-12-15 17:38:52 +13:00
Tom Hvitved
15caaa7ad6 Merge pull request #7377 from hvitved/csharp/overriable-class
C#: Introduce class `Overridable`
2021-12-14 20:01:12 +01:00
Mathias Vorreiter Pedersen
310353060e C++: Also fix the FP in 'cpp/comparison-canceling-subexpr'. 2021-12-14 17:08:10 +00:00
Mathias Vorreiter Pedersen
b2082cc3da C++: Fix false positive in 'cpp/cpp/comparison-of-identical-expressions'. 2021-12-14 16:39:25 +00:00
Mathias Vorreiter Pedersen
9d14a85f3f C++: Add false positive. 2021-12-14 16:38:19 +00:00
Erik Krogh Kristensen
dc9187778b QL: simplify the build/analyze workflow into a single workflow 2021-12-14 17:29:35 +01:00
Alex Ford
861ae856b3 Merge pull request #7391 from github/ruby/callnode-more-predicates
Ruby: Add `getBlock` and `getNumberOfArguments` predicates to `DataFlow::CallNode`
2021-12-14 16:10:13 +00:00
Erik Krogh Kristensen
f5788b9441 QL: adjust remaining workflows to work in the QL folder 2021-12-14 17:03:26 +01:00
Michael Nebel
edf472b9ed C#: Convert System.Xml.XmlReader flow to CSV format. 2021-12-14 16:01:40 +01:00
Erik Krogh Kristensen
fdb15d6073 QL: remove workflow that ran CodeQL with a published pack 2021-12-14 15:57:09 +01:00
Erik Krogh Kristensen
633597cc90 QL: remove the nightly ql-for-ql job 2021-12-14 15:57:09 +01:00
Erik Krogh Kristensen
b73b60d431 QL: remove the .devcontainer 2021-12-14 15:57:09 +01:00
Erik Krogh Kristensen
08b06422ff QL: remove repo-tests 2021-12-14 15:57:09 +01:00
Michael Nebel
a04920f241 C#: Convert System.Xml.XmlDocument flow to CSV format. 2021-12-14 15:56:55 +01:00
Michael Nebel
4bf2a514ac C#: XmlDocument only has instance Load methods. 2021-12-14 15:55:28 +01:00
Michael Nebel
376ee33707 C#: Convert System.Xml.XmlNode flow to CSV format. 2021-12-14 15:55:23 +01:00
Michael Nebel
4a71aa2165 C#: Update the flow summaries test expected output. 2021-12-14 15:53:16 +01:00
Michael Nebel
fc3299801b C#: Fix issue with summary tests, such that the output is compatiable with flow summary interpreter. 2021-12-14 15:53:16 +01:00
Michael Nebel
2cac729598 C#: Convert System.Xml.XmlNamedNodeMap flow to CSV format. 2021-12-14 15:53:11 +01:00
Michael Nebel
c5728b2951 Merge pull request #7389 from michaelnebel/csharp-mad-io
C#: Convert flow summaries to CSV for System.IO.*
2021-12-14 15:49:08 +01:00
Bas van Schaik
80b9ccff2b Merge pull request #7388 from github/sj-patch-log4j-query-description
Clarify Log4jJndiInjection.ql query name and help
2021-12-14 14:32:17 +00:00
Tom Hvitved
e882cdaca4 Ruby: Add missing getCallable() for nested destructured parameters 2021-12-14 15:04:40 +01:00
Tom Hvitved
10b2a0a54a Ruby: Add test for nested destructured parameters 2021-12-14 15:04:40 +01:00
Tom Hvitved
9ea8b20e77 Ruby: Deprecate Pattern classes 2021-12-14 15:04:40 +01:00
Tony Torralba
68a0efaf0c Formatting 2021-12-14 14:53:38 +01:00
Erik Krogh Kristensen
8eac1dcf15 QL: move .vscode folder inside the ql subfolder 2021-12-14 14:39:03 +01:00
Erik Krogh Kristensen
56a8cdb171 move files and folder, except dotfiles, into a ql subfolder 2021-12-14 14:34:53 +01:00
Erik Krogh Kristensen
d06ac78e4d QL: move files and folder, except dotfiles, into a ql subfolder 2021-12-14 14:34:53 +01:00
Alex Ford
3262a14f22 Ruby: use DataFlow::CallNode#getBlock to remove a cast 2021-12-14 13:23:38 +00:00
Tom Hvitved
b524a6104d Merge pull request #7368 from github/hvitved-patch-1
Update creating-codeql-databases.rst
2021-12-14 14:12:21 +01:00
Michael Nebel
b921fc62b8 C#: Some manual modifications to the System.IO flow summaries. 2021-12-14 14:02:25 +01:00
Alex Ford
f3dcccb64b Ruby: Add getBlock and getNumberOfArguments predicates to DataFlow::CallNode 2021-12-14 12:58:15 +00:00
Michael Nebel
c1cf44b342 C#: Remove unneeded imports. 2021-12-14 13:47:57 +01:00
Michael Nebel
16bcb4ec86 C#: Convert System.IO.Path flow to CSV format. 2021-12-14 13:44:27 +01:00
Michael Nebel
ca5c6923da C#: Convert System.IO.Compression flow to CSV format. 2021-12-14 13:37:08 +01:00
Bas van Schaik
d85ed9ea7a Clarify Log4jJndiInjection.ql query help 2021-12-14 12:32:36 +00:00
Asger Feldthaus
7e947b2a65 JS: Use return value of trusted type policy callback as a sink 2021-12-14 13:28:46 +01:00
Michael Nebel
45e416b87b C#: Convert System.IO.Stream flow to CSV format. 2021-12-14 13:28:25 +01:00
Michael Nebel
dd1ae0bbb5 C#: Convert System.IO.MemoryStream flow to CSV format. 2021-12-14 13:23:26 +01:00
Chris Smowton
85ff57bae6 Merge pull request #7354 from atorralba/atorralba/log4j-rce-experimental-query
Java: Experimental query for Log4j JNDI Injection
2021-12-14 11:32:13 +00:00
Tom Hvitved
a9c438924e C#: Introduce class Overridable
The class `Overridable` generalizes the existing class `Virtualizable` by also
including accessors. This allows for quite a bit of code to be simplified.
2021-12-14 10:52:13 +01:00
Tom Hvitved
8d607e6251 Docs: Add paragraph about C# shared compilation 2021-12-14 10:40:07 +01:00
Tom Hvitved
37d76f5e49 Merge pull request #6791 from hvitved/csharp/update-nuget-packages
C#: Update nuget packages
2021-12-14 10:20:15 +01:00
Mathias Vorreiter Pedersen
6fda5e8f5b Merge pull request #7272 from github/redsun82/cpp-overrunning-write-precision-split
C++: refactor buffer overwrite queries with estimate reasons
2021-12-14 08:50:30 +00:00
Ian Wright
1c79d1f985 Merge pull request #7352 from github/esbena/atm-endpoint-polish
ATM Endpoint filtering improvements
2021-12-14 08:19:23 +00:00
Paolo Tranquilli
0d7d60eebd C++: add small docstring fix 2021-12-14 08:15:45 +00:00
Tamás Vajk
81dedfe22f Merge pull request #7381 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-12-14 08:42:43 +01:00
Tony Torralba
aee617f911 Autoformat 2021-12-14 08:40:30 +01:00
github-actions[bot]
3c57602653 Add changed framework coverage reports 2021-12-14 00:09:54 +00:00
Harry Maclean
f21948d0ca Ruby: Speed up private method modelling 2021-12-14 11:10:38 +13:00
Esben Sparre Andreasen
1949a4e59a autoformat 2021-12-13 22:21:52 +01:00
Erik Krogh Kristensen
de4458346f Merge pull request #7344 from SZFsir/main
JS: Improve inter-procedural type inference for FunctionExpr
2021-12-13 21:58:53 +01:00
Tony Torralba
1b761b3d12 Apply suggestions from code review 2021-12-13 20:38:06 +01:00
Tony Torralba
ff2f5a5f91 Apply suggestions from code review
Co-authored-by: Bas van Schaik <5082246+sj@users.noreply.github.com>
2021-12-13 19:44:38 +01:00
Tony Torralba
d2dc19900f Apply suggestions from code review
Co-authored-by: Bas van Schaik <5082246+sj@users.noreply.github.com>
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-12-13 19:39:52 +01:00
Nick Rolfe
dc27089714 Merge pull request #7375 from github/nickrolfe/cargo_update
Ruby: update crate versions
2021-12-13 18:16:29 +00:00
Dave Bartolomeo
7732c0885f Merge pull request #7374 from aeisenberg/aesenberg/upgrades-semver
Fix semver for upgrades references
2021-12-13 13:06:59 -05:00
Andrew Eisenberg
0669ef505e Fix semver for upgrades references
Ensure the version range is flexible enough to handle
future version changes.
2021-12-13 09:03:33 -08:00
Aditya Sharad
372f099850 Merge pull request #7323 from adityasharad/atm/perf-debugging-std-lib
JS: Performance improvements to libraries using regex matching
2021-12-13 08:53:11 -08:00
Nick Rolfe
b18f7a9bd7 Ruby: update crate versions 2021-12-13 15:37:35 +00:00
Michael Nebel
c0b61d7f73 Merge pull request #7370 from michaelnebel/csharp-mad-textreader
C#: Flow summaries for virtual members in abstract classes should also apply to overrides.
2021-12-13 15:00:54 +01:00
Alex Ford
124aac23c6 Merge pull request #7371 from github/ruby/comment-new-syntax
Ruby: use Ruby object instantiation syntax in a comment
2021-12-13 13:23:03 +00:00
Alex Ford
4ae92667e1 Ruby: use Ruby object instantiation syntax in a comment 2021-12-13 12:54:45 +00:00
Michael Nebel
ba23393c0d C#: Update test as we now also implicitly gets flow summary for StreamReader. 2021-12-13 13:51:53 +01:00
Michael Nebel
a6eba04793 C#: Convert System.IO.TextReader flow to CSV format. 2021-12-13 13:51:18 +01:00
Esben Sparre Andreasen
c66d29998e update test output for additional DatabaseAccesses 2021-12-13 13:42:28 +01:00
Michael Nebel
88bb8a2704 C#: Update flow summaries test cases. 2021-12-13 13:14:49 +01:00
Michael Nebel
d699ca9aa8 C#: Flow summaries should also apply for overides or virtual members in abstract classes. 2021-12-13 13:09:40 +01:00
Paolo Tranquilli
5ed7056707 C++: remove deprecation from getMaxData 2021-12-13 11:28:02 +00:00
Paolo Tranquilli
3734e1ca4f C++: auto format 2021-12-13 11:28:02 +00:00
Paolo Tranquilli
06acaef43e C++: fix deprecation comments in BufferWrite 2021-12-13 11:28:02 +00:00
Paolo Tranquilli
a089898220 C++: remove reason from OverrunWrite output 2021-12-13 11:28:02 +00:00
Paolo Tranquilli
85de6dd667 C++: make BufferWrite changes backward compatible 2021-12-13 11:28:02 +00:00
Paolo Tranquilli
88d65b8fcb C++: postpone change-notes addition
We can add it later when more consistent changes to the queries are made
2021-12-13 11:28:02 +00:00
Paolo Tranquilli
2020786fb0 C++: fix format 2021-12-13 11:28:02 +00:00
Paolo Tranquilli
b0242dc55b C++: more idiomatic BufferWriteEstimationReason 2021-12-13 11:28:02 +00:00
Paolo Tranquilli
160635ba3c C++: add missing docs for a toString predicate 2021-12-13 11:28:02 +00:00
Paolo Tranquilli
a6cbe6f94c C++: add missing change note and docs 2021-12-13 11:28:02 +00:00
Paolo Tranquilli
fb03561a31 C++: add docstrings to Printf and BufferWrite 2021-12-13 11:28:02 +00:00
Paolo Tranquilli
aa68c51797 C++: preserve Printf and BufferWrite API 2021-12-13 11:28:02 +00:00
Paolo Tranquilli
598f283715 C++: add reason to buffer write estimations 2021-12-13 11:28:02 +00:00
Tamas Vajk
26194be8b6 Add workaround for equal lambda parameter symbols with different hashcodes 2021-12-13 11:59:24 +01:00
Michael Nebel
7ff2ee695d Merge pull request #7348 from michaelnebel/csharp-mad-as-csv-json
C#: Convert flow summaries for JSon.NET
2021-12-13 11:57:55 +01:00
JrXnm
efc9e67ec2 Update javascript/ql/lib/semmle/javascript/dataflow/internal/InterProceduralTypeInference.qll
Fix multiple declare may mismatch issue

Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2021-12-13 18:36:06 +08:00
JrXnm
fad95d8935 Update javascript/ql/lib/semmle/javascript/dataflow/internal/InterProceduralTypeInference.qll
Commit coding style suggestion

Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2021-12-13 18:32:11 +08:00
Michael Nebel
f32d464c0f C#: Ensure bi-directional import for External flow. 2021-12-13 10:50:49 +01:00
Michael Nebel
327cf444f4 C#: Convert Newtonsoft.JSon.Linq.JObject and Newtonsoft.JSon.Linq.JToken flow to CSV format. 2021-12-13 10:50:49 +01:00
Michael Nebel
f3c0eadbce C#: Fix the existing callableFlow for JObject to target the inherited ToString methods from JToken. 2021-12-13 10:50:49 +01:00
Michael Nebel
58f36e4b31 C#: Convert NewtonSoft.Json.JSonSerializer flow to CSV format. 2021-12-13 10:50:49 +01:00
Michael Nebel
90e49508a3 C#: Convert Newtonsoft.Json.JsonConvert flow to CSV format. 2021-12-13 10:50:48 +01:00
Michael Nebel
a4bea05fa7 Merge pull request #7342 from michaelnebel/csharp-mad-as-csv3
C#: More Flow summaries in CSV format.
2021-12-13 10:32:28 +01:00
Tom Hvitved
6f65f22db6 Update creating-codeql-databases.rst
Always use `/p:UseSharedCompilation=false` for `msbuild` / `dotnet build`.
2021-12-13 10:15:42 +01:00
Michael Nebel
be1e75471e C#: Ensure bi-directional import for external flow. 2021-12-13 09:23:11 +01:00
Michael Nebel
1cab177f8a C#: Convert System.Web.HttpUtility flow to CSV format. 2021-12-13 09:19:41 +01:00
Michael Nebel
0e0c3e3937 C#: Convert System.Web.HttpServerUtility flow to CSV format. 2021-12-13 09:19:41 +01:00
Michael Nebel
6301e726ee C#: Update HttpServerUtility stub with HtmlEncode method and update flow summaries test. 2021-12-13 09:19:41 +01:00
Michael Nebel
1cd37dddf5 C#: Convert System.Net.WebUtility flow to CSV format. 2021-12-13 09:19:41 +01:00
Michael Nebel
07a4f5f748 C#: Update FlowSummaries test as the bogus flow summaries for the KeyValuePair default constructor has been removed. 2021-12-13 09:19:41 +01:00
Michael Nebel
679aad138e C#: Convert System.Collections.Generic.KeyValuePair flow to CSV format. 2021-12-13 09:19:36 +01:00
Michael Nebel
42bf866fb3 C#: Convert System.Web.UI.WebControls.Textbox flow to CSV format. 2021-12-13 09:18:34 +01:00
Michael Nebel
9604ed883c C#: Convert System.NET.IPHostEntry flow to CSV format. 2021-12-13 09:17:27 +01:00
Michael Nebel
d804893a49 C#: Convert System.Net.Cookie flow to CSV format. 2021-12-13 09:16:05 +01:00
Michael Nebel
03fb244545 C#: Convert System.Web.HttpCookie flow to CSV format. 2021-12-13 09:13:14 +01:00
Michael Nebel
a6360215f3 Merge pull request #7304 from michaelnebel/csharp-mad-as-csv2
C#: Convert flow summaries to CSV format.
2021-12-13 08:56:06 +01:00
Harry Maclean
0ca9852cc8 Merge pull request #7325 from github/hmac/action-controller-private-methods
Ruby: Don't count private methods as Rails actions
2021-12-13 20:47:22 +13:00
Harry Maclean
6223b166c2 Update test fixtures
At the same time, rename some classes in `private.rb` so they don't
interact with identically-named modules in `calls.rb`.
2021-12-13 16:24:25 +13:00
Harry Maclean
e1d290d4c0 Ruby: Don't count private methods as Rails actions
Private instance methods on ActionController classes aren't valid
request handlers. Routing to them will raise an exception.
2021-12-13 15:36:55 +13:00
Aditya Sharad
1857de1f33 JS: Speed up detection of jQuery marker comments
Combine two regexes into a single one.
This saves up to 5s on large databases by reducing the number
of separate scans of the comments table before regex matching.

The combined regex is slightly more permissive than the
original two, since it allows a combination of the two
matched formats. A string that matches one of the original
regexes will match the combined regex.
2021-12-10 15:30:02 -08:00
Nick Rolfe
b80a84c156 Merge pull request #7341 from github/nickrolfe/cookies 2021-12-10 19:52:23 +00:00
Aditya Sharad
6a1aea740f JS: Avoid scanning individual comment lines to find generated code markers
Some subclasses of GeneratedCodeMarkerComment regex match against `getLine(_)`.
When evaluated, this results in multiple scans (one per subclass that uses it)
of all comment lines in the database, before regex matching against those lines.

To make these scans smaller, regex match against the entire comment text
without splitting them into lines.
This is achieved using `?m` (multiline) and line boundaries in the regexes.
2021-12-10 11:41:54 -08:00
Aditya Sharad
c9a87234ef JS: Factor helper predicate to improve SensitiveWrite performance 2021-12-10 11:41:53 -08:00
Andrew Eisenberg
66c1629974 Merge pull request #7285 from github/post-release-prep-2.7.3-ddd4ccbb
Post-release preparation 2.7.3
2021-12-10 09:59:45 -08:00
Tony Torralba
43a10457dd [Java] Query for Log4j JNDI Injection 2021-12-10 17:37:43 +01:00
Nick Rolfe
b6c5b4d213 Ruby: define ActionViewCookiesCall 2021-12-10 16:36:26 +00:00
yoff
d8857c7ce8 Merge pull request #7246 from tausbn/python/import-star-flow
Python: Support flow through `import *`
2021-12-10 16:34:32 +01:00
Henry Mercer
a46787ea07 Merge pull request #7351 from github/henrymercer/js-atm-heuristic-sinks-improvements
JS: Improve handling of heuristic sinks in endpoint filters
2021-12-10 14:56:45 +00:00
Rasmus Wriedt Larsen
bd9b96e154 Merge pull request #7331 from tausbn/python-fix-bad-callsite-points-to-join
Python: Fix bad `callsite_points_to` join
2021-12-10 15:39:49 +01:00
Rasmus Wriedt Larsen
8ee020f79c Merge pull request #7332 from tausbn/python-fix-bad-scope-entry-points-to-join
Python: Fix bad `scope_entry_points_to` join
2021-12-10 15:33:13 +01:00
Esben Sparre Andreasen
13288be7fc make ATM anti sink model for dojo.require 2021-12-10 15:07:51 +01:00
Esben Sparre Andreasen
9ffc02944d add file write model for express-fileupload mv 2021-12-10 15:05:34 +01:00
Esben Sparre Andreasen
cfd2dcffa0 recognize more modelled database accesses 2021-12-10 14:54:59 +01:00
Esben Sparre Andreasen
b0f6cf1491 expose more marsdb calls as database accesses 2021-12-10 13:46:19 +01:00
Esben Sparre Andreasen
9df1ac7f75 treat redis and ioredis usage as database access 2021-12-10 13:26:26 +01:00
Esben Sparre Andreasen
10498c3643 treat jQuery as fully modelled 2021-12-10 12:51:45 +01:00
Esben Sparre Andreasen
a1ee900f50 treat Base64 manipulations as non-sinks 2021-12-10 12:37:44 +01:00
Henry Mercer
6e167040f5 Merge pull request #7307 from adityasharad/atm/perf-debugging
JS/ATM: Various compilation fixes and performance improvements
2021-12-10 11:00:27 +00:00
Tom Hvitved
657cd89286 Merge pull request #7347 from hvitved/cfg/more-consistency-tests
Shared CFG: Add two more consistency queries
2021-12-10 10:50:39 +01:00
Tamas Vajk
d2822c2acc Rework semantic model caching 2021-12-10 10:42:30 +01:00
Tamas Vajk
704a5e4bbf Revert "C#: Avoid NPE in Parameter.Populate"
This reverts commit 08eb7e207d1e12c9578e07ee0a1d79bf6b62f60f.
2021-12-10 10:42:30 +01:00
Tom Hvitved
8ccbcf1bf8 C#: Avoid NPE in Parameter.Populate 2021-12-10 10:42:29 +01:00
Tom Hvitved
563b771163 C#: Update expected test output 2021-12-10 10:42:29 +01:00
Tom Hvitved
0a0657ada1 C#: Adapt to new Roslyn representation of implicit Main methods 2021-12-10 10:42:29 +01:00
Tom Hvitved
1c230d0888 C#: Update nuget packages 2021-12-10 10:42:29 +01:00
Michael Nebel
afa58f5676 C#: Ensure bi-directional importing of external flow for System.Text. 2021-12-10 10:28:35 +01:00
Arthur Baars
13f7fd88f1 Merge pull request #7283 from aibaars/ruby-pattern-matching-cfg
Ruby: pattern matching: CFG
2021-12-10 10:24:38 +01:00
Anders Schack-Mulligen
634ed91904 Merge pull request #7346 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-12-10 10:12:23 +01:00
Tom Hvitved
cf42427f54 Merge pull request #7321 from hvitved/csharp/cil/unique-type
C#: Avoid CIL instructions with multiple types
2021-12-10 09:58:06 +01:00
Tom Hvitved
f7f3890b40 Merge pull request #7320 from hvitved/csharp/unknown-type
C#: Populate `UnknownType`
2021-12-10 09:57:55 +01:00
Tom Hvitved
70f76d06c7 Shared CFG: Add two more consistency queries 2021-12-10 09:56:50 +01:00
Tom Hvitved
45c0d4a3b2 Merge pull request #7343 from hvitved/cfg/consistency-test
Shared CFG: Add another consistency test
2021-12-10 09:49:05 +01:00
Asger Feldthaus
b336c29283 JS: Track functions with methods 2021-12-10 09:38:29 +01:00
Asger Feldthaus
4ef2a5f4f1 JS: Add test 2021-12-10 09:38:29 +01:00
github-actions[bot]
7e5bfa5aa0 Add changed framework coverage reports 2021-12-10 00:09:34 +00:00
Aditya Sharad
271b23ba8f JS: Expand explanatory comment about version placeholders 2021-12-09 13:43:08 -08:00
Aditya Sharad
0c3daabc51 JS: Fix broken regex matching predicate
The receiver string and the regex were in the wrong order,
leading to test failures when looking for matching comments.
2021-12-09 13:42:33 -08:00
Chris Smowton
753d886b0d Merge pull request #6319 from haby0/java/MyBatisSqlInjection
[Java] CWE-089 MyBatis Mapper Sql Injection
2021-12-09 19:57:18 +00:00
Taus
6d247bfdf9 Merge pull request #7330 from tausbn/python-fix-bad-adjacentuseuse-join
Python: Fix bad join in SSA
2021-12-09 20:55:45 +01:00
Erik Krogh Kristensen
e7209d1ee1 Merge pull request #7216 from erik-krogh/ts45
JS: Add support for TypeScript 4.5
2021-12-09 20:33:52 +01:00
Chris Smowton
75f3ebf051 Fix OTHER XML tag 2021-12-09 17:55:03 +00:00
Chris Smowton
9f69c75c50 Fix XML tag 2021-12-09 17:44:49 +00:00
Chris Smowton
2cd70b96cd Fix doctype 2021-12-09 17:44:08 +00:00
JrXnm
1a1a7413c2 JS: Improv inter-procedural type inference for FunctionExpr 2021-12-10 01:09:49 +08:00
Michael Nebel
d60b90acd3 C#: Manual update of System.String and System.Convert flow summaries. 2021-12-09 16:34:42 +01:00
Michael Nebel
e879ca7a3b C#: Convert System.Convert flow to CSV format. 2021-12-09 16:34:42 +01:00
Michael Nebel
15b4b218c8 C#: Convert System.Nullable<> flow to CSV format. 2021-12-09 16:34:42 +01:00
Michael Nebel
bbab0e582a C#: Convert System.Lazy<> flow to CSV format. 2021-12-09 16:34:42 +01:00
Michael Nebel
9e61dfb41f C#: Convert System.Text.StringBuilder flow to CSV format. 2021-12-09 16:34:41 +01:00
Michael Nebel
5a26346ba5 C#: Allow the use of pointer types in CSV validation. 2021-12-09 16:34:41 +01:00
Michael Nebel
5376eb89b3 C#: Convert System.String flow to CSV format. 2021-12-09 16:34:41 +01:00
Michael Nebel
df482a9603 Merge pull request #7314 from michaelnebel/csharp-stubs-dataflow-global
C#: Update tests dataflow/global tests to use stubs.
2021-12-09 16:31:39 +01:00
Chris Smowton
470256da85 Copyedit 2021-12-09 15:10:07 +00:00
Tony Torralba
8bba3eb2b6 Merge pull request #6823 from atorralba/atorralba/android-notification-models
Android: Add models for `android.app.Notification` builders
2021-12-09 16:01:44 +01:00
Henry Mercer
f08f07e19e JS: Improve handling of heuristic sinks in endpoint filters
Previously heuristic sinks were always included, to avoid us filtering
them out due to not being an argument to an external library call.
In this commit we move the argument to an external library call
filtering to the query-specific endpoint filters.
This lets us filter out heuristic sinks if they match one of the other
endpoint filters, reducing FPs.
2021-12-09 15:00:54 +00:00
Chris Smowton
d0a19fffee Copyedit 2021-12-09 14:58:29 +00:00
Tom Hvitved
7e99426141 C#: Address review comments 2021-12-09 15:51:54 +01:00
Tom Hvitved
2bf5966fe3 C#: Address review comment 2021-12-09 15:44:43 +01:00
Arthur Baars
fd4915a564 Ruby: CFG: add default implementation for getAnInnerCompatibleCompletion 2021-12-09 15:23:26 +01:00
Arthur Baars
9d288c90a5 Ruby: CFG: better return type for getAMatchingSuccessorType 2021-12-09 15:23:26 +01:00
Arthur Baars
a7b3f1370f Ruby: CFG: add test case 2021-12-09 15:23:26 +01:00
Arthur Baars
d0aa307bd3 Ruby: CFG: fix multiple successors failure for default parameters 2021-12-09 15:23:26 +01:00
Tom Hvitved
b887165005 Ruby: Code review suggestions 2021-12-09 15:23:26 +01:00
Arthur Baars
3689481c18 Ruby: CFG: make Completion.isValidFor work for getSugared AST nodes 2021-12-09 15:23:26 +01:00
Arthur Baars
660e52f2bf Ruby: CFG: make VariableReferencePattern a PreOrder node 2021-12-09 15:23:26 +01:00
Arthur Baars
e9e3ef3ea2 Ruby: 'self' is not really a local variable 2021-12-09 15:23:26 +01:00
Arthur Baars
799c945299 Ruby: fix CFG for AsPattern 2021-12-09 15:23:26 +01:00
Arthur Baars
95f8f85aa2 Ruby: fix allowed completions for desugared CasePatterns 2021-12-09 15:23:26 +01:00
Arthur Baars
aacba0b522 Ruby: CFG: add test cases for pattern matching 2021-12-09 15:23:26 +01:00
Arthur Baars
513fe09dbb Treat class names in array/find/hash patterns as sub-patterns 2021-12-09 15:23:26 +01:00
Arthur Baars
d17c055139 CFG 2021-12-09 15:23:25 +01:00
Arthur Baars
44a615839d Add test case with rest variable and no prefix elements 2021-12-09 15:23:25 +01:00
Arthur Baars
f08eb8e616 Revert "Temporarily allow CFG inconsistencies"
This reverts commit dca1e34cd8.
2021-12-09 15:23:25 +01:00
Michael Nebel
69f42b9c74 C#: Update remaining tests. 2021-12-09 15:21:08 +01:00
Tony Torralba
38250b0821 Remove unnecessary implicit read step 2021-12-09 15:18:38 +01:00
Tom Hvitved
cbc96dba8a Shared CFG: Add another consistency test
Finds nodes with multiple normal successors, where one is the special simple
successor. For example, this would flag a node that has both a "simple" and
a "true" successor.
2021-12-09 15:08:19 +01:00
Tony Torralba
522a4bb9fa Propagate extras through build methods 2021-12-09 14:56:52 +01:00
yoff
8e11c2c476 Merge pull request #7259 from RasmusWL/even-more-path-injection-sinks
Python: Add more path-injection sinks from `os` and `tempfile` modules
2021-12-09 14:46:41 +01:00
Michael Nebel
992801b7cb C#: Update GetAnOutNode test. 2021-12-09 13:55:04 +01:00
Tom Hvitved
9ffa236c51 Merge pull request #7288 from hvitved/cfg/enclosing-scope
Shared CFG: Include CFG scope in `TElementNode`
2021-12-09 13:39:48 +01:00
Tony Torralba
c0c40cc05b Remove synthetic fields 2021-12-09 13:34:41 +01:00
Tony Torralba
3a3c7fc59e Fix stub 2021-12-09 13:34:41 +01:00
Tony Torralba
f209ff4f76 Use synthetic fields to improve taint precision 2021-12-09 13:34:39 +01:00
Tony Torralba
b7f7c5ba20 Change format of fluent models to make review easier 2021-12-09 13:33:19 +01:00
Tony Torralba
f63ffb0630 Add models for Notification builders 2021-12-09 13:33:17 +01:00
Tom Hvitved
069cf9d17f C#: Exclude stubs in GetAnOutNode.ql test 2021-12-09 13:33:14 +01:00
Tom Hvitved
cbd21edc99 C#: Override File::isFromSource in tests to exclude stubs 2021-12-09 13:33:14 +01:00
Michael Nebel
2f85735b6a C#: Use stubs instead of dll's in the dataflow global tests. 2021-12-09 13:25:11 +01:00
Tom Hvitved
69ba2e6f8c Merge pull request #7337 from michaelnebel/csharp-synthetic-field
C#: Introduce synthetic fields and use them in Task<>.
2021-12-09 13:18:44 +01:00
Nick Rolfe
d46564caa6 Ruby: treat ActionController#cookies as a remote flow source 2021-12-09 12:13:17 +00:00
Nick Rolfe
f6a8b9a7e5 Ruby: add cookies call to frameworks test 2021-12-09 12:07:04 +00:00
Taus
b871342e83 Python: A small further performance improvement
Unrolling the transitive closure had slightly better performance here.

Also, we exclude names of builtins, since those will be handled by a
separate case of `isDefinedLocally`.
2021-12-09 10:29:55 +00:00
Michael Nebel
13347cd102 C#: Add Ql docs to synthetic fields. 2021-12-09 10:34:31 +01:00
Michael Nebel
9f4b965202 C#: Update the flow summaries produced for Task<> after introduction of synthetic fields. 2021-12-09 10:11:49 +01:00
Michael Nebel
d70d1fbf81 C#: Add support for the use of synthetic fields in flow summary CSV. 2021-12-09 10:11:48 +01:00
Michael Nebel
a43704ab43 C#: Update dataflow/global tests based on synthetic fields. 2021-12-09 10:11:48 +01:00
Michael Nebel
063398f24d C#: Use synthetic fields for Task instead of referring to private fields. 2021-12-09 10:11:48 +01:00
Michael Nebel
60f3ff8c33 C#: Introduce type for Synthetic fields. 2021-12-09 10:11:48 +01:00
Harry Maclean
8df5aaa797 Ruby: Model private class methods
`Module#private_class_method` takes a symbol representing the name of a
method in the current module scope and makes that module private. This
is similar to `private`, but applies only to class (singleton) methods.
Unlike `private`, it must be called with an argument, and does not
change the ambient visibility for any subsequent method definitions.

    class Foo
      def public
      end

      def private1
      end
      private_class_method :private1

      # This alternate form works because method definition
      # returns its name as a symbol:

      private_class_method def private2
      end
    end
2021-12-09 18:15:25 +13:00
Harry Maclean
e811ba1150 Ruby: handle private module methods
`private` can be used in both classes and modules.
2021-12-09 18:13:29 +13:00
haby0
8bcbf8e30f rename isMybatisCollectionTypeSqlInjection 2021-12-09 09:16:33 +08:00
Taus
8517eff0f7 Python: Fix bad performance
A few changes, all bundled together:

- We were getting a lot of magic applied to the predicates in the
  `ImportStar` module, and this was causing needless re-evaluation.
  To address this, the easiest solution was to simply cache the entire
  module.
- In order to separate this from the dataflow analysis and make it
  dependent only on control flow, `potentialImportStarBase` was changed
  to return a `ControlFlowNode`.
- `isDefinedLocally` was defined on control flow nodes, which meant we
  were duplicating a lot of tuples due to control flow splitting, to no
  actual benefit.

Finally, there was a really bad join in `isDefinedLocally` that was
fixed by separating out a helper predicate. This is a case where we
could use a three-way join, since the join between the `Scope`, the
`name` string and the `Name` is big no matter what.

If we join `scope_defines_name` with `n.getId()`, we'll get `Name`s
belonging to irrelevant scopes.

If we join `scope_defines_name` with the enclosing scope of the `Name`
`n`, then we'll get this also for `Name`s that don't share their `getId`
with the local variable defined in the scope.

If we join `n.getId()` with `n.getScope()...` then we'll get all
enclosing scopes for each `Name`.

The last of these is what we currently have. It's not terrible, but not
great either. (Though thankfully it's rare to have lots of enclosing
scopes.)
2021-12-08 22:53:45 +00:00
Tom Hvitved
b49ca6a24c Merge pull request #7335 from hvitved/ruby/dataflow/hide-desugared-nodes
Ruby: Hide desugared nodes in data-flow paths
2021-12-08 17:39:48 +01:00
haby0
a18aad8536 Fix one 2021-12-08 21:03:17 +08:00
Anders Schack-Mulligen
38d0bb4a60 Merge pull request #7260 from hvitved/dataflow/argument-parameter-matching
Data flow: Introduce `ParameterPosition` and `ArgumentPosition`
2021-12-08 12:49:08 +01:00
haby0
1d321c692b Refactor isMybatisXmlOrAnnotationSqlInjection 2021-12-08 18:59:55 +08:00
Tom Hvitved
283173ad02 Address review comments 2021-12-08 11:26:44 +01:00
Erik Krogh Kristensen
3145e8f9b7 add upgrade script 2021-12-08 10:53:47 +01:00
Tom Hvitved
5735bb698d Ruby: Hide desugared nodes in data-flow paths 2021-12-08 09:00:16 +01:00
Tom Hvitved
490872173a Data flow: Sync files 2021-12-07 20:29:18 +01:00
Tom Hvitved
07ca1c2ec0 Data flow: Adjust parameterMatch join-orders 2021-12-07 20:29:00 +01:00
Erik Krogh Kristensen
fe1a473f07 Merge pull request #138 from github/erik-krogh/bump-this
bump the severity of `ql/implicit-this`
2021-12-07 20:12:21 +01:00
Erik Krogh Kristensen
a722aeb5e3 QL: Merge pull request #138 from github/erik-krogh/bump-this
bump the severity of `ql/implicit-this`
2021-12-07 20:12:21 +01:00
Taus
e7c298d903 Python: Fix bad scope_entry_points_to join
From `pritomrajkhowa/LoopBound`:

```
Definitions.ql-7:PointsTo::PointsToInternal::scope_entry_points_to#ffff#antijoin_rhs#2 ........... 55.1s
```

specifically

```
(443s) Tuple counts for PointsTo::PointsToInternal::scope_entry_points_to#ffff#antijoin_rhs#2/3@74a7cart after 55.1s:
184070    ~0%        {3} r1 = JOIN PointsTo::PointsToInternal::scope_entry_points_to#ffff#shared#1 WITH Variables::GlobalVariable#class#f ON FIRST 1 OUTPUT Lhs.0 'arg2', Lhs.1 'arg0', Lhs.2 'arg1'
184070    ~0%        {3} r2 = STREAM DEDUP r1
919966523 ~2%        {4} r3 = JOIN r2 WITH Essa::EssaDefinition::getSourceVariable_dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'arg0', Lhs.2 'arg1', Lhs.0 'arg2'
4281779   ~2293%     {3} r4 = JOIN r3 WITH Essa::EssaVariable::getScope_dispred#ff ON FIRST 2 OUTPUT Lhs.1 'arg0', Lhs.2 'arg1', Lhs.3 'arg2'
                    return r4
```

First, this is an `antijoin`, so there's likely some negation involved.
Also, there's mention of `GlobalVariable`, `getScope`, and
`getSourceVariable`, none of which appear in `scope_entry_points_to`, so
it's likely that something got inlined.

Taking a closer look at the predicates mentioned in the body, we spot
`undefined_variable` as a likely culprit.

Evaluating this predicate in isolation reveals that it's not terribly
big, so we could try just marking it with `pragma[noinline]` (I opted
for the slightly more solid `nomagic`) and see how that fares. I also
checked that `builtin_not_in_outer_scope` was similarly small, and
made that one un-inlineable as well.

The result? Well, I can't even show you. Both `scope_entry_points_to`
and `undefined_variable` are so fast that they don't appear in the
clause timing report (so they can at most take 3.5s each to evaluate, as
that is the smallest timing in the list).
2021-12-07 18:51:44 +00:00
Taus
b502ca1ea7 Python: Fix bad callsite_points_to join
From `pritomrajkhowa/LoopBound`:

```
Definitions.ql-7:PointsTo::InterProceduralPointsTo::callsite_points_to#ffff#join_rhs#3 ........... 5m53s
```

specifically

```
(767s) Tuple counts for PointsTo::InterProceduralPointsTo::callsite_points_to#ffff#join_rhs#3/3@f8f86764 after 5m53s:
832806293 ~0%     {4} r1 = JOIN PointsTo::InterProceduralPointsTo::callsite_points_to#ffff#shared#1 WITH PointsTo::InterProceduralPointsTo::var_at_exit#fff ON FIRST 1 OUTPUT Lhs.0, Lhs.1 'arg1', Rhs.1 'arg2', Rhs.2 'arg0'
832806293 ~0%     {3} r2 = JOIN r1 WITH Essa::TEssaNodeRefinement#ffff_03#join_rhs ON FIRST 2 OUTPUT Lhs.3 'arg0', Lhs.1 'arg1', Lhs.2 'arg2'
                return r2
```

This one is a bit tricky to unpack. Where is this `shared#1` defined?

```
EVALUATE NONRECURSIVE RELATION:
SYNTHETIC PointsTo::InterProceduralPointsTo::callsite_points_to#ffff#shared#1(int arg0, numbered_tuple arg1) :-
    SENTINEL PointsTo::InterProceduralPointsTo::callsite_points_to#ffff#shared
    SENTINEL Definitions::EscapingAssignmentGlobalVariable#class#f
    SENTINEL Essa::TEssaNodeRefinement#ffff_03#join_rhs
    {2} r1 = JOIN PointsTo::InterProceduralPointsTo::callsite_points_to#ffff#shared WITH Definitions::EscapingAssignmentGlobalVariable#class#f ON FIRST 1 OUTPUT Lhs.0 'arg0', Lhs.1 'arg1'
    {2} r2 = STREAM DEDUP r1
    {2} r3 = JOIN r2 WITH Essa::TEssaNodeRefinement#ffff_03#join_rhs ON FIRST 2 OUTPUT Lhs.0 'arg0', Lhs.1 'arg1'
    {2} r4 = STREAM DEDUP r3
    return r4
```

Looking at `callsite_points_to`, we see a likely candidate in `srcvar`.
It is guarded with an `instanceof` check for
`EscapingAssignmentGlobalVariable` (which lines up nicely with the
sentinel on its charpred) and `getSourceVariable` is just a projection
of `TEssaNodeRefinement`.

So let's try unbinding `srcvar` to prevent an early join.

The timing is now:

```
Definitions.ql-7:PointsTo::InterProceduralPointsTo::callsite_points_to#ffff ...................... 31.3s (2554 evaluations with max 101ms in PointsTo::InterProceduralPointsTo::callsite_points_to#ffff/4@i516#581fap5w)
```
(Showing the tuple counts doesn't make sense here, since all of the
`shared` and `join_rhs` predicates have been smooshed around.)
2021-12-07 18:25:53 +00:00
Taus
a716482c1f Python: Fix bad join in SSA
On `pritomrajkhowa/LoopBound`:

```
Definitions.ql-3:SsaCompute::SsaComputeImpl::AdjacentUsesImpl::adjacentUseUse#ff ................. 4m35s
```

specifically

```
(376s) Tuple counts for SsaCompute::SsaComputeImpl::AdjacentUsesImpl::adjacentUseUse#ff/2@be04e9kp after 4m58s:
388843     ~0%     {4} r1 = JOIN Essa::TPhiFunction#fff_2#join_rhs WITH SsaCompute::SsaComputeImpl::AdjacentUsesImpl::definesAt#ffff ON FIRST 1 OUTPUT Rhs.1, Lhs.0, Rhs.2, Rhs.3
3629812090 ~1%     {7} r2 = JOIN r1 WITH SsaCompute::SsaComputeImpl::variableUse#ffff ON FIRST 1 OUTPUT Lhs.0, Rhs.2, Rhs.3, Lhs.2, Lhs.3, Lhs.1, Rhs.1 'use1'
0          ~0%     {2} r3 = JOIN r2 WITH SsaCompute::SsaComputeImpl::AdjacentUsesImpl::adjacentVarRefs#fffff ON FIRST 5 OUTPUT Lhs.5, Lhs.6 'use1'
0          ~0%     {2} r4 = JOIN r3 WITH SsaCompute::SsaComputeImpl::AdjacentUsesImpl::firstUse#ff ON FIRST 1 OUTPUT Lhs.1 'use1', Rhs.1 'use2'

897141     ~0%     {2} r5 = SsaCompute::SsaComputeImpl::AdjacentUsesImpl::adjacentUseUseSameVar#ff UNION r4
                    return r5
```

Clearly we do not want to join on the variable so soon. So we unbind it
and get

```
(78s) Tuple counts for SsaCompute::SsaComputeImpl::AdjacentUsesImpl::adjacentUseUse#ff/2@40e0e6uv after 434ms:
3377959 ~2%     {4} r1 = SCAN SsaCompute::SsaComputeImpl::variableUse#ffff OUTPUT In.0, In.2, In.3, In.1 'use1'
1026855 ~2%     {4} r2 = JOIN r1 WITH SsaCompute::SsaComputeImpl::AdjacentUsesImpl::adjacentVarRefs#fffff ON FIRST 3 OUTPUT Lhs.0, Rhs.3, Rhs.4, Lhs.3 'use1'
129484  ~0%     {2} r3 = JOIN r2 WITH SsaCompute::SsaComputeImpl::AdjacentUsesImpl::definesAt#ffff_1230#join_rhs ON FIRST 3 OUTPUT Rhs.3, Lhs.3 'use1'
0       ~0%     {2} r4 = JOIN r3 WITH Essa::TPhiFunction#fff_2#join_rhs ON FIRST 1 OUTPUT Lhs.0, Lhs.1 'use1'
0       ~0%     {2} r5 = JOIN r4 WITH SsaCompute::SsaComputeImpl::AdjacentUsesImpl::firstUse#ff ON FIRST 1 OUTPUT Lhs.1 'use1', Rhs.1 'use2'

897141  ~0%     {2} r6 = SsaCompute::SsaComputeImpl::AdjacentUsesImpl::adjacentUseUseSameVar#ff UNION r5
                return r6
```
2021-12-07 18:19:47 +00:00
Henry Mercer
322e39446d JS: Autoformat 2021-12-07 14:17:11 +00:00
Henry Mercer
016727d6b6 JS: Fix occasional duplicate body tokens
0e31439 introduces some occasional duplicate tokens due to duplicate AST
node attributes. The long-term fix is to update `CodeToFeatures.qll`,
but for the short-term, we update the concatenation to concatenate
unique (location, token) pairs.
2021-12-07 14:16:48 +00:00
Asger Feldthaus
23480b2d8f JS: Remove stray TODO 2021-12-07 10:49:14 +01:00
Asger F
614c80706f Apply suggestions from code review
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2021-12-07 10:48:44 +01:00
Asger Feldthaus
5559681916 JS: Change note 2021-12-07 10:46:18 +01:00
Asger Feldthaus
635ac0a209 JS: Fix perf issue in data flow step generation 2021-12-07 10:46:18 +01:00
Asger Feldthaus
da8e67b7ee JS: Use routing trees to detect deeply tainted req.body 2021-12-07 10:46:18 +01:00
Asger Feldthaus
7492293c5b JS: Add test with route handler indirection 2021-12-07 10:46:18 +01:00
Asger Feldthaus
3cbe94ac0a JS: Add consistency checks to TemplateObjectInjection test 2021-12-07 10:46:18 +01:00
Asger Feldthaus
64db70f3ac JS: Add explicit body-parsers to TemplateObjectInjection test 2021-12-07 10:46:18 +01:00
Asger Feldthaus
8af430d40f JS: Shift line numbers in TemplateObjectInjection test 2021-12-07 10:46:17 +01:00
Asger Feldthaus
5f8ea3965d JS: Do not flag auth endpoints that are immune to Login CSRF 2021-12-07 10:46:17 +01:00
Asger Feldthaus
66b1612e5e JS: Treat non-cookie based auth as CSRF preventer 2021-12-07 10:46:17 +01:00
Asger Feldthaus
b73219392b JS: Improve precision of missing CSRF middleware 2021-12-07 10:46:17 +01:00
Asger Feldthaus
d0e94e655d JS: Exclude error handling from auth calls 2021-12-07 10:46:17 +01:00
Asger Feldthaus
400bf10cc3 JS: Move fastify-specific route handler step into extension point 2021-12-07 10:46:17 +01:00
Asger Feldthaus
71820569e1 JS: Instantiate for Fastify 2021-12-07 10:46:15 +01:00
Asger Feldthaus
cfb9265f0a JS: Add template steps for res.locals.x 2021-12-07 10:44:53 +01:00
Asger Feldthaus
5269933461 JS: Port missing rate limiting query 2021-12-07 10:44:19 +01:00
Asger Feldthaus
389a3c9073 JS: Port CSRF query 2021-12-07 10:43:06 +01:00
Asger Feldthaus
16fa066636 JS: Fix false negative in Mongo model 2021-12-07 10:43:05 +01:00
Asger Feldthaus
3dd5d4d7b4 JS: Instantiate for Express and add tests 2021-12-07 10:43:03 +01:00
Erik Krogh Kristensen
3ebf1e3c13 Add codeql-go sources (894102defd) 2021-12-07 10:42:38 +01:00
Erik Krogh Kristensen
a3d11c61a8 QL: Add codeql-go sources (894102defd) 2021-12-07 10:42:38 +01:00
Erik Krogh Kristensen
d852b28653 Add codeql sources (3c59aa319e) 2021-12-07 10:42:34 +01:00
Erik Krogh Kristensen
44c3787457 QL: Add codeql sources (3c59aa319e) 2021-12-07 10:42:34 +01:00
Asger Feldthaus
aae4260819 JS: Routing model 2021-12-07 10:41:55 +01:00
Asger Feldthaus
e9575c3df6 JS: Support AdditionalUseStep in API graphs 2021-12-07 10:41:52 +01:00
Taus
7cd9369d91 Python: Autoformat 2021-12-07 09:29:24 +00:00
Taus
33a9f86f54 Python: Change integer in trois.py 2021-12-07 08:54:07 +00:00
Taus
dd33f4f4d2 Python: Apply suggestions from code review
Co-authored-by: yoff <lerchedahl@gmail.com>
2021-12-07 09:48:53 +01:00
Tom Hvitved
243b92b28c C#: Avoid CIL instructions with multiple types 2021-12-06 14:42:41 +01:00
Tom Hvitved
60c0bcf8f7 C#: Include dup instructions in CIL ExprMissingType consistency test 2021-12-06 14:37:07 +01:00
Tom Hvitved
c39fe59a04 C#: Populate UnknownType 2021-12-06 14:09:17 +01:00
haby0
daf6a4ce07 Partial modification 2 2021-12-04 17:45:02 +08:00
Aditya Sharad
f68a40f82b JS: Simplify calculation of token features for endpoints
Use a `strictcount` to identify whether there is exactly one feature or not.
If so, we use it. If not, we use the empty string.
Add context to ensure we filter the set of data flow nodes down to only
the set of endpoint nodes.

This performance optimisation avoids calculating the Cartesian product
of data flow nodes and feature names, but it does not avoid calculating
the (slightly smaller) Cartesian product of endpoint nodes and feature names.
Product size = number of endpoint nodes * number of feature names.
At time of writing there are 8 feature names.
2021-12-03 14:20:27 -08:00
Aditya Sharad
fac2769d85 JS: Replace an exists+concat with an equivalent strictconcat 2021-12-03 14:20:26 -08:00
Aditya Sharad
0e31439b7e JS: Simplify aggregation of tokens into entity strings
Change the cutoff logic from `count` to `strictcount`, since we know it only applies
to a non-empty set of results.

Use a single `strictconcat` aggregate to combine tokens in order of location,
instead of computing a `rank` followed by a `concat`.

Strictness introduces a slight change of behaviour because missing tokens will now result
in no results from the predicate rather than an empty feature string.
2021-12-03 14:20:26 -08:00
Aditya Sharad
2a3b5fc2b2 JS: Performance optimisation for matching framework libraries with their marker comments
The `matchMarkerComment` predicate performs badly on any codebase with
a moderately large number of comments, because the current implementation
has to first compute the Cartesian product between the set of comments
and the set of framework library comment regexes.

Instead, match first against a single regex:
the union of all framework library comment regexes.
This computes a more benign Cartesian product, the same size as the set of comments.

See inline comments for more details.
2021-12-03 14:20:26 -08:00
Aditya Sharad
d0840afb80 JS: Fix compilation errors in EndpointFeatures library
Use the LabelParameter API instead of manually constructing the edge label.
2021-12-03 14:20:17 -08:00
haby0
6c6113b85b Partial modification 2021-12-03 18:59:24 +08:00
Tom Hvitved
d9704d7b39 Ruby: Adapt to shared CFG changes 2021-12-03 09:37:41 +01:00
Tom Hvitved
42f6dfc197 Sync files 2021-12-03 09:37:41 +01:00
Tom Hvitved
404f4a81a7 C#: Include CFG scope in TElementNode 2021-12-03 09:37:41 +01:00
Taus
7f44cebed7 Python: Add missing hidden flow
The easiest way to implement this was to change the definition of
`module_export` to account for chains of `import *`. We reuse the
machinery from `ImportStar.qll` for this, naturally.
2021-12-02 17:11:56 +00:00
Taus
4138296ec6 Python: Add test for "hidden" import * flow
TL;DR: We were missing out on flow in the following situation:

`mod1.py`:
```python
foo = SOURCE
```

`mod2.py`:
```python
from mod1 import *
```

`test.py`:
```python
from mod2 import foo
SINK(foo)
```

This is because there's no node at which a read of `foo` takes place
within `test.py`, and so the added reads make no difference.

Unfortunately, this means the previous test was a bit too simplistic,
since it only looks for module variable reads and writes. Because of
this, we change the test to be a more traditional "all flow" style
(though restricted to `CfgNode`s).
2021-12-02 17:05:54 +00:00
github-actions[bot]
87b968f337 Post-release preparation 2.7.3 2021-12-02 00:46:55 +00:00
Erik Krogh Kristensen
73f2f52ed8 use the TYPE_ONLY_IMPORT context 2021-12-01 14:54:16 +01:00
Erik Krogh Kristensen
739906b60c rename @import_or_export_declaration to @type_keyword_operand 2021-12-01 14:47:11 +01:00
Erik Krogh Kristensen
de53727ab3 remove spurious whitespace
Co-authored-by: Asger F <asgerf@github.com>
2021-12-01 14:29:57 +01:00
haby0
6742beae1b use <code> tags 2021-12-01 16:24:46 +08:00
Tom Hvitved
31374b485c Data flow: Update documentation 2021-12-01 09:01:06 +01:00
Tom Hvitved
e410244fe0 Python: Implement ParameterPosition et al 2021-12-01 08:51:22 +01:00
Tom Hvitved
bb8f4bb7c1 Ruby: Implement ParameterPosition et al 2021-12-01 08:51:22 +01:00
Tom Hvitved
ae6501d906 Java: Implement ParameterPosition et al 2021-12-01 08:51:22 +01:00
haby0
08be8edbce Modify according to suggestions 2021-12-01 11:57:57 +08:00
Andrew Eisenberg
ddd4ccbb4b Merge pull request #7274 from github/aeisenberg/add-version-policy
Add a version policy
2021-11-30 14:51:30 -08:00
Andrew Eisenberg
ff030534ff Add a version policy
Handles the post release process.
2021-11-30 14:47:48 -08:00
Dave Bartolomeo
b42295801b Merge pull request #7271 from github/release-prep/2.7.3
Release preparation for version 2.7.3
2021-11-30 17:29:46 -05:00
github-actions[bot]
337ce65fe5 Release preparation for version 2.7.3 2021-11-30 20:39:35 +00:00
Tom Hvitved
35a67845cf C++: Implement ParameterPosition et al 2021-11-30 15:34:16 +01:00
Tom Hvitved
540ecf3c21 Data flow: Sync files 2021-11-30 15:20:20 +01:00
Tom Hvitved
755085e9fe C#: Introduce ParameterPosition and ArgumentPosition 2021-11-30 15:20:20 +01:00
Dave Bartolomeo
9f6c0991cf Catch up with recent change notes 2021-11-29 16:41:18 -05:00
Dave Bartolomeo
5ed9029143 Move change notes to correct directories 2021-11-29 16:31:11 -05:00
Dave Bartolomeo
75fb47c76f Ruby change notes 2021-11-29 16:17:19 -05:00
Dave Bartolomeo
cd8a10d0a5 Python change notes 2021-11-29 16:17:05 -05:00
Dave Bartolomeo
96deddf053 JavaScript change notes 2021-11-29 16:16:30 -05:00
Dave Bartolomeo
452685bb66 Fix change note path 2021-11-29 16:11:34 -05:00
Dave Bartolomeo
310ef79fbd C++ change notes 2021-11-29 16:10:33 -05:00
Dave Bartolomeo
d0dac03bad Manually bump versions 2021-11-29 14:21:08 -05:00
Dave Bartolomeo
2dfcd1dd9c Add groups property
Also removed versions from test packs
2021-11-29 14:15:53 -05:00
Rasmus Wriedt Larsen
cbd7434a7e Python: Add modeling of tempfile module 2021-11-29 15:08:36 +01:00
Rasmus Wriedt Larsen
b68538376c Python: Add tests of tempfile module 2021-11-29 15:08:36 +01:00
Rasmus Wriedt Larsen
3bcf6d68ce Python: Refactor os FileSystemAccess change-note
I think it's more readable to have only one to cover all of these
changes, even though they came in through different PRs.
2021-11-29 15:08:18 +01:00
Rasmus Wriedt Larsen
58f92764f7 Python: Model more file access from os module 2021-11-29 14:54:02 +01:00
Rasmus Wriedt Larsen
fd23fa94a5 Python: Remove dubious fstat* modeling
These operate on file descriptors, and not on paths. file descriptors
doesn't fit into the rest of our modeling, so I would rather remove them
than to make it look like it's properly handled.

I also did not include any of the functions that work on file
descriptors when looking through all of `os`. So this keeps everything
consistent at least ;)
2021-11-29 14:54:02 +01:00
Rasmus Wriedt Larsen
e79b8f3e23 Python: Treat os.exec*, os.spawn*, and os.posix_spawn* as FileSystemAccess 2021-11-29 14:54:02 +01:00
Rasmus Wriedt Larsen
d2d5cce787 Python: Recognize keyword arguments for os.*spawn* calls 2021-11-29 14:54:02 +01:00
Rasmus Wriedt Larsen
14590436f9 Python: Expand tests for os.exec*, os.spawn*, and os.posix_spawn* 2021-11-29 14:54:02 +01:00
Rasmus Wriedt Larsen
50d3592ad3 Python: Add more complete tests of os module
I went through https://docs.python.org/3.10/library/os.html in order,
and added all the functions that works on paths.

`lstat` and `statvfs` were already modeled, but did not have any tests.
2021-11-29 14:54:02 +01:00
Rasmus Wriedt Larsen
a91208fd2c Python: Fix kwarg modeling for os.path.isdir 2021-11-29 14:54:02 +01:00
Rasmus Wriedt Larsen
36f14b31bc Python: Add explicit tests for kwargs
I also renamed the arguments to match what the keyword argument is
called. It doesn't matter too much for these specific tests, but for the
tests I'm about to add, it makes things a lot easier to get an overview
of.

Oh, and a test failure :O
2021-11-29 14:54:02 +01:00
Rasmus Wriedt Larsen
82602014ad Python: Minor refactor to use os.path.<func>
Since that's the idiomatic way to use this module
2021-11-29 14:54:02 +01:00
Erik Krogh Kristensen
fdcc144a98 add test for import assertions 2021-11-29 13:51:28 +01:00
Erik Krogh Kristensen
591aeff906 add TypeScript test for new private field syntax 2021-11-29 13:51:28 +01:00
Erik Krogh Kristensen
19bbe6d276 add JavaScript support for new private fields syntax 2021-11-29 13:51:25 +01:00
Erik Krogh Kristensen
d1a7feebc4 disable import resolution on type-only import specifiers 2021-11-29 13:49:10 +01:00
Erik Krogh Kristensen
d946802057 add support for type-only import specifiers 2021-11-29 13:49:10 +01:00
Erik Krogh Kristensen
57399b733e add test for String types as Discriminants 2021-11-29 13:49:10 +01:00
Erik Krogh Kristensen
0e890fd788 add test for the Awaited type 2021-11-29 13:49:10 +01:00
Erik Krogh Kristensen
eef3905c46 update expected output. The TypeScript compiler now emits types in more cases 2021-11-29 13:49:10 +01:00
Erik Krogh Kristensen
9ce248c829 update to TypeScript 4.5.2 2021-11-29 13:49:10 +01:00
Erik Krogh Kristensen
8e1b4e3a58 bump the severity of ql/implicit-this 2021-11-29 10:55:59 +01:00
Erik Krogh Kristensen
da5c2fb415 QL: bump the severity of ql/implicit-this 2021-11-29 10:55:59 +01:00
haby0
db04a0dadf New model: SQL injection in MyBatis annotations 2021-11-28 14:43:57 +08:00
Pavel Lobashov
6d339e50a3 Fix ruby incorrect version in some readme files
There is no `ruby 3.02` version - there is `ruby 3.0.2`
2021-11-27 22:44:27 +03:00
Taus
09a11f4166 Python: Update ImpliesDataflow test
Turns out that now we can resolve the convoluted imports. Hurray!
2021-11-26 14:47:25 +00:00
Taus
6c3aabe1df Python: Support flow through import *
Adds result for `ModuleVariableNode::getARead` corresponding to reads
that go through (chains of) `import *`.

This required a bit of a change to _which_ module variables we define.
Previously, we only included variables that were accessed elsewhere in
the same file, but now we must ensure to also include variables that may
be accessed through `import *`.
2021-11-26 13:49:08 +00:00
Taus
c3e495efe9 Python: Refactor built-ins and import * logic
Moves this from the API graphs implementation into separate files.
2021-11-26 13:49:08 +00:00
Taus
03b6ee3833 Python: Add import * test
This test shows off a few things:

- transitive chains of `import *`
- multiple modules exporting the same name (to test for cross-talk)
2021-11-26 13:49:08 +00:00
haby0
04a3f76a8b Eliminate false positives of Mybatis Configuration Variable 2021-11-25 15:47:37 +08:00
haby0
d36a7ed10e add test case 2021-11-25 15:47:32 +08:00
haby0
99c8b291b2 add sink 2021-11-25 15:47:32 +08:00
haby0
b8732859de Add isSanitizerGuard, verify file path 2021-11-25 15:47:31 +08:00
haby0
31400df0d4 Modify sink and improve SQL injection detection 2021-11-25 15:47:30 +08:00
haby0
69690a2509 Modify sinks 2021-11-25 15:47:30 +08:00
haby0
4438f8c58c Add MyBatis Mapper Sql Injection 2021-11-25 15:47:29 +08:00
Erik Krogh Kristensen
e25f03fb56 Merge pull request #137 from github/erik-krogh/even-more-consistency
even more consistency
2021-11-19 13:39:36 +01:00
Erik Krogh Kristensen
172684ce6e QL: Merge pull request #137 from github/erik-krogh/even-more-consistency
even more consistency
2021-11-19 13:39:36 +01:00
Erik Krogh Kristensen
a86f2c3ed1 Add codeql sources (1f3f7e9ccc) 2021-11-19 13:15:06 +01:00
Erik Krogh Kristensen
70f6493d7a QL: Add codeql sources (1f3f7e9ccc) 2021-11-19 13:15:06 +01:00
Erik Krogh Kristensen
1a0379a894 introduce type resolution consistency checks 2021-11-18 18:44:34 +01:00
Erik Krogh Kristensen
d89e430db2 QL: introduce type resolution consistency checks 2021-11-18 18:44:34 +01:00
Erik Krogh Kristensen
15b56585f9 update inefficientStringComparison, to avoid underscores 2021-11-18 18:43:54 +01:00
Erik Krogh Kristensen
37c2db240c QL: update inefficientStringComparison, to avoid underscores 2021-11-18 18:43:54 +01:00
Erik Krogh Kristensen
036d749378 Merge pull request #126 from github/erik-krogh/update-sources
update sources
2021-11-18 14:32:01 +01:00
Erik Krogh Kristensen
44ffc7e155 QL: Merge pull request #126 from github/erik-krogh/update-sources
update sources
2021-11-18 14:32:01 +01:00
Erik Krogh Kristensen
a0bf13007c remove codeql-ruby sources 2021-11-18 14:15:19 +01:00
Erik Krogh Kristensen
9a6c9c4d77 QL: remove codeql-ruby sources 2021-11-18 14:15:19 +01:00
Erik Krogh Kristensen
e3c0e190d9 Add codeql-go sources (4cae4b23fc) 2021-11-18 14:14:20 +01:00
Erik Krogh Kristensen
fe097783a7 QL: Add codeql-go sources (4cae4b23fc) 2021-11-18 14:14:20 +01:00
Erik Krogh Kristensen
61b71807df Add codeql sources (6c2713dd8b) 2021-11-18 14:14:17 +01:00
Erik Krogh Kristensen
fa54855995 QL: Add codeql sources (6c2713dd8b) 2021-11-18 14:14:17 +01:00
Erik Krogh Kristensen
fb40b8a032 update import script 2021-11-18 14:13:47 +01:00
Erik Krogh Kristensen
c07d55325e QL: update import script 2021-11-18 14:13:47 +01:00
Erik Krogh Kristensen
349b556c26 Merge pull request #129 from github/erik-krogh/cartesian
various new improvements and queries
2021-11-18 13:16:53 +01:00
Erik Krogh Kristensen
1b070f1dd8 QL: Merge pull request #129 from github/erik-krogh/cartesian
various new improvements and queries
2021-11-18 13:16:53 +01:00
Erik Krogh Kristensen
38b925b19c rename "use matches" query, and refactor into Query.qll 2021-11-18 13:05:41 +01:00
Erik Krogh Kristensen
d64c7fc638 QL: rename "use matches" query, and refactor into Query.qll 2021-11-18 13:05:41 +01:00
Erik Krogh Kristensen
89604deb8d add redundant inline cast query 2021-11-18 12:23:55 +01:00
Erik Krogh Kristensen
d8bf7ed6e0 QL: add redundant inline cast query 2021-11-18 12:23:55 +01:00
Erik Krogh Kristensen
97461d1f11 add var unused in disjunct query 2021-11-18 12:23:09 +01:00
Erik Krogh Kristensen
12a3fa77f6 QL: add var unused in disjunct query 2021-11-18 12:23:09 +01:00
Erik Krogh Kristensen
112cd9d29c move use-set-literal implementation to Query.qll file 2021-11-18 12:23:09 +01:00
Erik Krogh Kristensen
1cbacc41d7 QL: move use-set-literal implementation to Query.qll file 2021-11-18 12:23:09 +01:00
Erik Krogh Kristensen
33d363eb94 move use-instanceof implementation to Query.qll, and rename the .ql file 2021-11-18 12:23:09 +01:00
Erik Krogh Kristensen
f320414b1c QL: move use-instanceof implementation to Query.qll, and rename the .ql file 2021-11-18 12:23:09 +01:00
Erik Krogh Kristensen
45def1b124 move implementation of implicit-this to Query.qll file 2021-11-18 12:23:09 +01:00
Erik Krogh Kristensen
28444c7e9c QL: move implementation of implicit-this to Query.qll file 2021-11-18 12:23:09 +01:00
Erik Krogh Kristensen
ac4476fa82 performance improvements 2021-11-18 12:23:09 +01:00
Erik Krogh Kristensen
c3f362876b QL: performance improvements 2021-11-18 12:23:09 +01:00
Erik Krogh Kristensen
84d277dc94 add getLeft/getRight helper predicates to disjunction/conjunction 2021-11-18 12:23:09 +01:00
Erik Krogh Kristensen
0154f4eba4 QL: add getLeft/getRight helper predicates to disjunction/conjunction 2021-11-18 12:23:09 +01:00
Erik Krogh Kristensen
9d308ba0bd refactor away the ComparisonOp ast class 2021-11-18 12:23:07 +01:00
Erik Krogh Kristensen
7c82c5e378 QL: refactor away the ComparisonOp ast class 2021-11-18 12:23:07 +01:00
Erik Krogh Kristensen
5a76e7d4f8 introduce FieldDecl in the ast 2021-11-18 12:08:28 +01:00
Erik Krogh Kristensen
1b19a3e320 QL: introduce FieldDecl in the ast 2021-11-18 12:08:28 +01:00
Erik Krogh Kristensen
cc16fdecbb Merge pull request #130 from github/erik-krogh/more-types
Better type resolution
2021-11-16 17:52:15 +01:00
Erik Krogh Kristensen
f54f70d707 QL: Merge pull request #130 from github/erik-krogh/more-types
Better type resolution
2021-11-16 17:52:15 +01:00
Taus
7214d70ee7 Merge pull request #135 from github/winfix
Fix create-extractor-pack.ps1
2021-10-20 14:51:06 +02:00
Taus
fff1f1248a QL: Merge pull request #135 from github/winfix
Fix create-extractor-pack.ps1
2021-10-20 14:51:06 +02:00
Geoffrey White
1f2b32fe87 Fix create-extractor-pack.ps1 2021-10-20 13:17:22 +01:00
Geoffrey White
3bc209ded8 QL: Fix create-extractor-pack.ps1 2021-10-20 13:17:22 +01:00
Erik Krogh Kristensen
631a503e55 cleanup 2021-10-19 09:19:31 +02:00
Erik Krogh Kristensen
c00e18f4b0 QL: cleanup 2021-10-19 09:19:31 +02:00
Esben Sparre Andreasen
629605c075 Merge pull request #133 from github/esbena/update-readme
Update readme with alerts and actions information
2021-10-19 07:58:59 +02:00
Esben Sparre Andreasen
ac78e26672 QL: Merge pull request #133 from github/esbena/update-readme
Update readme with alerts and actions information
2021-10-19 07:58:59 +02:00
Esben Sparre Andreasen
0760c1c13f Update readme with alerts and actions information 2021-10-19 07:58:22 +02:00
Esben Sparre Andreasen
769f787651 QL: Update readme with alerts and actions information 2021-10-19 07:58:22 +02:00
Esben Sparre Andreasen
3f420c442e Update bleeding-codeql-analysis.yml 2021-10-18 21:51:56 +02:00
Esben Sparre Andreasen
5fa1c04e2a QL: Update bleeding-codeql-analysis.yml 2021-10-18 21:51:56 +02:00
Esben Sparre Andreasen
b96ad387ef Merge pull request #132 from github/esbena/fix-branch
change branch name
2021-10-18 21:18:16 +02:00
Esben Sparre Andreasen
032a0dc6ae QL: Merge pull request #132 from github/esbena/fix-branch
change branch name
2021-10-18 21:18:16 +02:00
Esben Sparre Andreasen
e851ba2bfd change code-scanning branch 2021-10-18 20:58:02 +02:00
Esben Sparre Andreasen
d49db9298c QL: change code-scanning branch 2021-10-18 20:58:02 +02:00
Esben Sparre Andreasen
a089e0ed3f change branch name 2021-10-18 12:31:03 +02:00
Esben Sparre Andreasen
6cc14b16ba QL: change branch name 2021-10-18 12:31:03 +02:00
Esben Sparre Andreasen
a9cef84b90 Merge pull request #131 from github/esbena/workflow-improvements
Misc. workflow improvements
2021-10-18 12:21:39 +02:00
Esben Sparre Andreasen
f29813b3f7 QL: Merge pull request #131 from github/esbena/workflow-improvements
Misc. workflow improvements
2021-10-18 12:21:39 +02:00
Esben Sparre Andreasen
eded7b8da1 add nightly-changes workflow 2021-10-18 12:03:16 +02:00
Esben Sparre Andreasen
dc715af18b QL: add nightly-changes workflow 2021-10-18 12:03:16 +02:00
Esben Sparre Andreasen
c200ec38f5 use workflow_call in bleeding-codeql-analysis.yml 2021-10-18 12:03:16 +02:00
Esben Sparre Andreasen
7e2b00e62c QL: use workflow_call in bleeding-codeql-analysis.yml 2021-10-18 12:03:16 +02:00
Erik Krogh Kristensen
509e77bbdb add nonTotalGetParent to the list of empty consistency queries 2021-10-17 15:09:30 +02:00
Erik Krogh Kristensen
ef6ea195db QL: add nonTotalGetParent to the list of empty consistency queries 2021-10-17 15:09:30 +02:00
Erik Krogh Kristensen
9a73c36389 add support for libraryPathDependencies in qlpacks 2021-10-17 14:51:00 +02:00
Erik Krogh Kristensen
9e4e42847b QL: add support for libraryPathDependencies in qlpacks 2021-10-17 14:51:00 +02:00
Erik Krogh Kristensen
ade206184c fix broken import in unused file 2021-10-17 14:44:41 +02:00
Erik Krogh Kristensen
b317d73c83 QL: fix broken import in unused file 2021-10-17 14:44:41 +02:00
Erik Krogh Kristensen
09f60f20fc fix code-scanning alert 2021-10-17 14:00:26 +02:00
Erik Krogh Kristensen
89979890ad QL: fix code-scanning alert 2021-10-17 14:00:26 +02:00
Erik Krogh Kristensen
18eede5597 fix some inconsistencies related to primitive types 2021-10-17 13:38:40 +02:00
Erik Krogh Kristensen
48d4fcd064 QL: fix some inconsistencies related to primitive types 2021-10-17 13:38:40 +02:00
Erik Krogh Kristensen
9127fa533a fix predicate resolution 2021-10-17 12:53:49 +02:00
Erik Krogh Kristensen
4db6702caa QL: fix predicate resolution 2021-10-17 12:53:49 +02:00
Erik Krogh Kristensen
dc354f8fbf add noResolvePredicateExpr to the list of empty consistency predicates 2021-10-17 11:59:51 +02:00
Erik Krogh Kristensen
9681119f68 QL: add noResolvePredicateExpr to the list of empty consistency predicates 2021-10-17 11:59:51 +02:00
Erik Krogh Kristensen
055937eefb NewTypeBranches are Predicates 2021-10-17 11:58:00 +02:00
Erik Krogh Kristensen
6cec64466f QL: NewTypeBranches are Predicates 2021-10-17 11:58:00 +02:00
Erik Krogh Kristensen
2af3fb5cca add test for predicateExpr 2021-10-17 11:57:07 +02:00
Erik Krogh Kristensen
8ad5b34c07 QL: add test for predicateExpr 2021-10-17 11:57:07 +02:00
Erik Krogh Kristensen
9d9663d842 and consistency query that will highlight new consistency errors 2021-10-16 23:17:42 +02:00
Erik Krogh Kristensen
84d2cb84c1 QL: and consistency query that will highlight new consistency errors 2021-10-16 23:17:42 +02:00
Erik Krogh Kristensen
74b1c19a20 only resolve imports to qll files, and not e.g. dbschemes 2021-10-16 23:09:48 +02:00
Erik Krogh Kristensen
1b9793d928 QL: only resolve imports to qll files, and not e.g. dbschemes 2021-10-16 23:09:48 +02:00
Erik Krogh Kristensen
b31ea30e85 better support for getType on super 2021-10-16 22:22:52 +02:00
Erik Krogh Kristensen
a65289253e QL: better support for getType on super 2021-10-16 22:22:52 +02:00
Erik Krogh Kristensen
f99ce113cb resolve super-expressions when the super-type is explicitly mentioned 2021-10-16 21:55:36 +02:00
Erik Krogh Kristensen
928b91d975 QL: resolve super-expressions when the super-type is explicitly mentioned 2021-10-16 21:55:36 +02:00
Erik Krogh Kristensen
c43ff2f9d0 add test for super-types 2021-10-16 21:54:23 +02:00
Erik Krogh Kristensen
4c32b7e480 QL: add test for super-types 2021-10-16 21:54:23 +02:00
Erik Krogh Kristensen
c1b011d47c better type resolution of add expressions 2021-10-16 21:35:02 +02:00
Erik Krogh Kristensen
34d4e55459 QL: better type resolution of add expressions 2021-10-16 21:35:02 +02:00
Erik Krogh Kristensen
2a5d567041 add test for type resolution 2021-10-16 21:32:25 +02:00
Erik Krogh Kristensen
e528c6ff90 QL: add test for type resolution 2021-10-16 21:32:25 +02:00
Erik Krogh Kristensen
6004ecc3a4 Merge pull request #125 from github/erik-krogh/fix-my-own-mistake
fixing the callgraph
2021-10-15 22:15:29 +02:00
Erik Krogh Kristensen
efff86e47b QL: Merge pull request #125 from github/erik-krogh/fix-my-own-mistake
fixing the callgraph
2021-10-15 22:15:29 +02:00
Erik Krogh Kristensen
f19a229e6f find dbscheme files that are contained within a subfolder 2021-10-15 21:37:23 +02:00
Erik Krogh Kristensen
865e4f0441 QL: find dbscheme files that are contained within a subfolder 2021-10-15 21:37:23 +02:00
Erik Krogh Kristensen
3b1c04b71c correctly resolve super calls in char preds 2021-10-15 21:28:19 +02:00
Erik Krogh Kristensen
e060708367 QL: correctly resolve super calls in char preds 2021-10-15 21:28:19 +02:00
Erik Krogh Kristensen
145efa4a1a improve resolution of buildin predicates (and getAQlClass()) 2021-10-15 21:23:18 +02:00
Erik Krogh Kristensen
3252c04c38 QL: improve resolution of buildin predicates (and getAQlClass()) 2021-10-15 21:23:18 +02:00
Erik Krogh Kristensen
f8138c92c5 fix getEnclosingModule, which broke the callgraph 2021-10-15 19:48:47 +02:00
Erik Krogh Kristensen
1239b1aee1 QL: fix getEnclosingModule, which broke the callgraph 2021-10-15 19:48:47 +02:00
Erik Krogh Kristensen
7ce2750c8a add missing getChild() relations 2021-10-15 19:48:47 +02:00
Erik Krogh Kristensen
c7aa89b1d8 QL: add missing getChild() relations 2021-10-15 19:48:47 +02:00
Erik Krogh Kristensen
535904e545 add failing callgraph test 2021-10-15 19:48:45 +02:00
Erik Krogh Kristensen
b40e30790a QL: add failing callgraph test 2021-10-15 19:48:45 +02:00
Erik Krogh Kristensen
d0aa219652 add an consistency test for the totality of getParent() 2021-10-15 19:46:51 +02:00
Erik Krogh Kristensen
8391580301 QL: add an consistency test for the totality of getParent() 2021-10-15 19:46:51 +02:00
Taus
d950b59a4d Merge pull request #124 from github/erik-krogh/fix-step-performance
fix performance of the transitive step query
2021-10-15 19:11:31 +02:00
Taus
9a02a223e3 QL: Merge pull request #124 from github/erik-krogh/fix-step-performance
fix performance of the transitive step query
2021-10-15 19:11:31 +02:00
Mathias Vorreiter Pedersen
299500fdaa Merge pull request #109 from github/missing-nomagic
QL: Query for finding missing `nomagic` on cand predicates
2021-10-15 17:59:59 +01:00
Mathias Vorreiter Pedersen
24334e4a3a QL: Merge pull request #109 from github/missing-nomagic
QL: Query for finding missing `nomagic` on cand predicates
2021-10-15 17:59:59 +01:00
Erik Krogh Kristensen
62355f3f0e fix performance of the transitive step query 2021-10-15 18:47:54 +02:00
Erik Krogh Kristensen
0bfedc74fa QL: fix performance of the transitive step query 2021-10-15 18:47:54 +02:00
Mathias Vorreiter Pedersen
dbc3b49777 Merge branch 'main' into missing-nomagic 2021-10-15 17:26:09 +01:00
Mathias Vorreiter Pedersen
188a6b19f0 QL: Merge branch 'main' into missing-nomagic 2021-10-15 17:26:09 +01:00
Mathias Vorreiter Pedersen
df3d5aefc7 Merge pull request #119 from github/query-depends-on-tostring
Query: Query logic depends on `toString`
2021-10-15 16:15:54 +01:00
Mathias Vorreiter Pedersen
02c26037cb QL: Merge pull request #119 from github/query-depends-on-tostring
Query: Query logic depends on `toString`
2021-10-15 16:15:54 +01:00
Mathias Vorreiter Pedersen
f5bb1d0124 QL: Respond to PR reviews. 2021-10-15 16:02:23 +01:00
Mathias Vorreiter Pedersen
4d5901a421 QL: QL: Respond to PR reviews. 2021-10-15 16:02:23 +01:00
Taus
eb787ae321 Merge pull request #95 from github/tausbn/add-override-test
Add test for `override`
2021-10-15 16:00:15 +02:00
Taus
d6dd752764 QL: Merge pull request #95 from github/tausbn/add-override-test
Add test for `override`
2021-10-15 16:00:15 +02:00
Mathias Vorreiter Pedersen
ed17bd9106 Merge pull request #123 from github/tausbn/add-instanceof-super-resolution
Support `super` with `instanceof`
2021-10-15 14:15:37 +01:00
Mathias Vorreiter Pedersen
5dbeaa17d6 QL: Merge pull request #123 from github/tausbn/add-instanceof-super-resolution
Support `super` with `instanceof`
2021-10-15 14:15:37 +01:00
Taus
5b261d88bb Support super with instanceof 2021-10-15 12:27:24 +00:00
Taus
1375e1d9fc QL: Support super with instanceof 2021-10-15 12:27:24 +00:00
Anders Schack-Mulligen
684600cc54 Merge pull request #104 from github/bidirectional-import
Query for finding missing or unwanted bidirectional imports of abstract classes
2021-10-15 14:02:58 +02:00
Anders Schack-Mulligen
370d75bedc QL: Merge pull request #104 from github/bidirectional-import
Query for finding missing or unwanted bidirectional imports of abstract classes
2021-10-15 14:02:58 +02:00
Taus
8ceeb71c8e Merge pull request #117 from github/tausbn/update-extractor-generator
Upgrade the extractor generator
2021-10-15 13:59:32 +02:00
Taus
7745a13efb QL: Merge pull request #117 from github/tausbn/update-extractor-generator
Upgrade the extractor generator
2021-10-15 13:59:32 +02:00
Mathias Vorreiter Pedersen
1469766994 QL: Reduce precision to 'medium'. 2021-10-15 12:57:32 +01:00
Mathias Vorreiter Pedersen
21caef3d7d QL: QL: Reduce precision to 'medium'. 2021-10-15 12:57:32 +01:00
Mathias Vorreiter Pedersen
67b65b691e Merge pull request #122 from github/aschackmull/library-annot
New query: Don't use library annotation.
2021-10-15 12:56:22 +01:00
Mathias Vorreiter Pedersen
ed15ee8dfb QL: Merge pull request #122 from github/aschackmull/library-annot
New query: Don't use library annotation.
2021-10-15 12:56:22 +01:00
Mathias Vorreiter Pedersen
30717310e7 Remove the dataflow library. 2021-10-15 12:40:49 +01:00
Mathias Vorreiter Pedersen
1d331fc678 QL: Remove the dataflow library. 2021-10-15 12:40:49 +01:00
Anders Schack-Mulligen
b0bbbc54d0 New query: Don't use library annotation. 2021-10-15 13:35:25 +02:00
Anders Schack-Mulligen
510f8253e5 QL: New query: Don't use library annotation. 2021-10-15 13:35:25 +02:00
Erik Krogh Kristensen
1a79b13bdc fix performance 2021-10-15 13:32:39 +02:00
Erik Krogh Kristensen
8aa354c4c0 QL: fix performance 2021-10-15 13:32:39 +02:00
Taus
10aeadb889 Fix bad merge 2021-10-15 11:12:52 +00:00
Taus
24959a52d0 QL: Fix bad merge 2021-10-15 11:12:52 +00:00
Taus
e185382c41 Update bleeding-codeql-analysis.yml 2021-10-15 11:06:53 +00:00
Taus
6f4370a684 QL: Update bleeding-codeql-analysis.yml 2021-10-15 11:06:53 +00:00
Taus
1fb8a175f9 Merge branch 'main' into tausbn/add-override-test 2021-10-15 13:03:17 +02:00
Taus
53cbde0c44 QL: Merge branch 'main' into tausbn/add-override-test 2021-10-15 13:03:17 +02:00
Taus
ccaef199bf Ignore overridden predicates in consistency check 2021-10-15 10:58:38 +00:00
Taus
9c82f72720 QL: Ignore overridden predicates in consistency check 2021-10-15 10:58:38 +00:00
Mathias Vorreiter Pedersen
c9f80b1052 QL: Add query for using toString in query logic. 2021-10-15 11:57:55 +01:00
Mathias Vorreiter Pedersen
d90de13bdb QL: QL: Add query for using toString in query logic. 2021-10-15 11:57:55 +01:00
Mathias Vorreiter Pedersen
5c70c6a19b QL: Add dataflow library. 2021-10-15 11:57:30 +01:00
Mathias Vorreiter Pedersen
4fe43155c0 QL: QL: Add dataflow library. 2021-10-15 11:57:30 +01:00
Taus
44fff659bd Fix dataset_measure.yml, hopefully
Also I forgot to add `TreeSitter.qll` to the path for the build, whoops.
2021-10-15 10:53:33 +00:00
Taus
85e5b689a3 QL: Fix dataset_measure.yml, hopefully
Also I forgot to add `TreeSitter.qll` to the path for the build, whoops.
2021-10-15 10:53:33 +00:00
Taus
2a0c29156f Update build.yml to supply generator args 2021-10-15 10:43:51 +00:00
Taus
e5dab0185d QL: Update build.yml to supply generator args 2021-10-15 10:43:51 +00:00
Taus
bd5243884a Merge pull request #116 from github/erik-krogh/qlpack-test
add test for qlpacks
2021-10-15 12:33:34 +02:00
Taus
4238a5be2f QL: Merge pull request #116 from github/erik-krogh/qlpack-test
add test for qlpacks
2021-10-15 12:33:34 +02:00
Taus
89d2f93a16 Merge branch 'main' into tausbn/update-extractor-generator 2021-10-15 12:28:01 +02:00
Taus
b75e19a446 QL: Merge branch 'main' into tausbn/update-extractor-generator 2021-10-15 12:28:01 +02:00
Anders Schack-Mulligen
6c70f5299d Remove some FPs. 2021-10-15 12:05:02 +02:00
Anders Schack-Mulligen
3fc0bed9b5 QL: Remove some FPs. 2021-10-15 12:05:02 +02:00
Taus
5ef7b9797e Also update qltest.cmd 2021-10-15 09:34:14 +00:00
Taus
514f8f3344 QL: Also update qltest.cmd 2021-10-15 09:34:14 +00:00
Taus
310ea6b69c Merge pull request #112 from github/tausbn/import-language-first
Query: Noninitial imports of the standard library
2021-10-15 11:30:02 +02:00
Taus
53e362c994 QL: Merge pull request #112 from github/tausbn/import-language-first
Query: Noninitial imports of the standard library
2021-10-15 11:30:02 +02:00
Erik Krogh Kristensen
741e4a7a38 add test for qlpacks, and get them to work 2021-10-15 11:24:18 +02:00
Erik Krogh Kristensen
0954584743 QL: add test for qlpacks, and get them to work 2021-10-15 11:24:18 +02:00
Taus
7f80514144 Autoformat 2021-10-15 09:21:24 +00:00
Taus
8020040b4f QL: Autoformat 2021-10-15 09:21:24 +00:00
Taus
816bfbe4ea Upgrade the extractor generator
For now, the grammar still includes dbscheme and YAML, but with this
change we should be able to separate these out into their own grammars.
2021-10-15 09:16:34 +00:00
Taus
9f4c829b3e QL: Upgrade the extractor generator
For now, the grammar still includes dbscheme and YAML, but with this
change we should be able to separate these out into their own grammars.
2021-10-15 09:16:34 +00:00
Erik Krogh Kristensen
e3d42a1fba remove leftover test predicate 2021-10-15 10:58:44 +02:00
Erik Krogh Kristensen
6fe7579fc3 QL: remove leftover test predicate 2021-10-15 10:58:44 +02:00
Geoffrey White
ee7ac53bf6 Merge pull request #107 from github/missing-qldoc
Add ql/missing-qldoc query.
2021-10-15 09:41:45 +01:00
Geoffrey White
2f77b921a0 QL: Merge pull request #107 from github/missing-qldoc
Add ql/missing-qldoc query.
2021-10-15 09:41:45 +01:00
Erik Krogh Kristensen
e6b07070f6 Merge pull request #102 from github/esbena/simple-codeql-action
make another codeql-action workflow that uses a published pack
2021-10-15 10:32:19 +02:00
Erik Krogh Kristensen
e862dfd3dc QL: Merge pull request #102 from github/esbena/simple-codeql-action
make another codeql-action workflow that uses a published pack
2021-10-15 10:32:19 +02:00
Taus
fed640b21f Merge pull request #114 from github/erik-krogh/consistency
fix the signature of regexpCapture and regexpFind
2021-10-15 10:12:19 +02:00
Taus
2352cf7a26 QL: Merge pull request #114 from github/erik-krogh/consistency
fix the signature of regexpCapture and regexpFind
2021-10-15 10:12:19 +02:00
Mathias Vorreiter Pedersen
e1871a2508 Merge pull request #86 from github/use-set-literal
New query: Use set literal
2021-10-15 08:55:30 +01:00
Mathias Vorreiter Pedersen
8e6bc11197 QL: Merge pull request #86 from github/use-set-literal
New query: Use set literal
2021-10-15 08:55:30 +01:00
Erik Krogh Kristensen
541dcb365f hook up consistency query 2021-10-15 09:31:54 +02:00
Erik Krogh Kristensen
ddc0ade28c QL: hook up consistency query 2021-10-15 09:31:54 +02:00
Erik Krogh Kristensen
29ebe7b13d add test 2021-10-15 09:31:54 +02:00
Erik Krogh Kristensen
f071da499b QL: add test 2021-10-15 09:31:54 +02:00
Erik Krogh Kristensen
1641d0fa93 update expected output 2021-10-15 09:31:54 +02:00
Erik Krogh Kristensen
6cd11d2e13 QL: update expected output 2021-10-15 09:31:54 +02:00
Erik Krogh Kristensen
f19dd78d40 fix getArity on PredicateOrBuiltin 2021-10-15 09:31:53 +02:00
Erik Krogh Kristensen
74a7945995 QL: fix getArity on PredicateOrBuiltin 2021-10-15 09:31:53 +02:00
Erik Krogh Kristensen
c31bd7a1e8 fix the signature of regexpCapture and regexpFind 2021-10-15 09:31:31 +02:00
Erik Krogh Kristensen
153f8fec0e QL: fix the signature of regexpCapture and regexpFind 2021-10-15 09:31:31 +02:00
Mathias Vorreiter Pedersen
50e80dc8b7 Merge pull request #113 from github/erik-krogh/fix-implcit-this
fix implicit this
2021-10-15 08:28:19 +01:00
Mathias Vorreiter Pedersen
f29457f4ca QL: Merge pull request #113 from github/erik-krogh/fix-implcit-this
fix implicit this
2021-10-15 08:28:19 +01:00
Erik Krogh Kristensen
016ff2af63 fix implicit this 2021-10-14 22:37:17 +02:00
Erik Krogh Kristensen
f9d8ae588c QL: fix implicit this 2021-10-14 22:37:17 +02:00
Taus
71f69997e2 Autoformat 2021-10-14 16:06:19 +00:00
Taus
632d42fe68 QL: Autoformat 2021-10-14 16:06:19 +00:00
Taus
c6a52ed2ea Query: Noninitial imports of the standard library
Finds a single result in

```
semmle.code.java.dataflow.internal.rangeanalysis.SignAnalysisSpecific.qll
```
which starts with

```ql
module Private {
  import semmle.code.java.dataflow.RangeUtils as RU
  private import semmle.code.java.dataflow.SSA as Ssa
  private import semmle.code.java.controlflow.Guards as G
  private import java as J
  private import Sign
  ...
```
2021-10-14 15:44:23 +00:00
Taus
37e9024343 QL: Query: Noninitial imports of the standard library
Finds a single result in

```
semmle.code.java.dataflow.internal.rangeanalysis.SignAnalysisSpecific.qll
```
which starts with

```ql
module Private {
  import semmle.code.java.dataflow.RangeUtils as RU
  private import semmle.code.java.dataflow.SSA as Ssa
  private import semmle.code.java.controlflow.Guards as G
  private import java as J
  private import Sign
  ...
```
2021-10-14 15:44:23 +00:00
Mathias Vorreiter Pedersen
4016a8e458 QL: Add query for finding missing nomagic on candidate predicates. 2021-10-14 15:46:22 +01:00
Mathias Vorreiter Pedersen
187c24e260 QL: QL: Add query for finding missing nomagic on candidate predicates. 2021-10-14 15:46:22 +01:00
Geoffrey White
0a3705b7af Add ql/missing-qldoc query. 2021-10-14 15:45:03 +01:00
Geoffrey White
ecf27ff24b QL: Add ql/missing-qldoc query. 2021-10-14 15:45:03 +01:00
Mathias Vorreiter Pedersen
3e2fb5a64e Merge pull request #105 from github/aschackmull/transitive-step
New performance query: Transitive step in recursion.
2021-10-14 15:28:33 +01:00
Mathias Vorreiter Pedersen
9330fa0f69 QL: Merge pull request #105 from github/aschackmull/transitive-step
New performance query: Transitive step in recursion.
2021-10-14 15:28:33 +01:00
Joe Farebrother
9b786c27c0 Fix isAbstract 2021-10-14 15:03:19 +01:00
Joe Farebrother
be36de9b0a QL: Fix isAbstract 2021-10-14 15:03:19 +01:00
Joe Farebrother
ec6a8b933c Query for finding missing or unwanted bidirectional imports of abstract classes 2021-10-14 15:02:08 +01:00
Joe Farebrother
1013cb4ccb QL: Query for finding missing or unwanted bidirectional imports of abstract classes 2021-10-14 15:02:08 +01:00
Anders Schack-Mulligen
ec292dbffd New performance query: Transitive step in recursion. 2021-10-14 15:42:40 +02:00
Anders Schack-Mulligen
dfa0e77e39 QL: New performance query: Transitive step in recursion. 2021-10-14 15:42:40 +02:00
Esben Sparre Andreasen
ab11bce776 document usage 2021-10-14 15:34:54 +02:00
Esben Sparre Andreasen
72d1473581 QL: document usage 2021-10-14 15:34:54 +02:00
Geoffrey White
76880e8f93 Autoformat and fix test. 2021-10-14 14:31:42 +01:00
Geoffrey White
e510593aa0 QL: Autoformat and fix test. 2021-10-14 14:31:42 +01:00
Esben Sparre Andreasen
d23de3dcd8 make another codeql-action workflow that uses a published pack 2021-10-14 15:29:06 +02:00
Esben Sparre Andreasen
b611b5100b QL: make another codeql-action workflow that uses a published pack 2021-10-14 15:29:06 +02:00
Geoffrey White
6af28e37ae We can use PredicateOrBuiltin now. 2021-10-14 13:59:47 +01:00
Geoffrey White
6d313cfb6b QL: We can use PredicateOrBuiltin now. 2021-10-14 13:59:47 +01:00
Geoffrey White
9b52ad2d3d Work around import of internal file. 2021-10-14 13:59:40 +01:00
Geoffrey White
fe8b466ff0 QL: Work around import of internal file. 2021-10-14 13:59:40 +01:00
Geoffrey White
a665e94805 Merge branch 'main' into use-set-literal 2021-10-14 13:55:40 +01:00
Geoffrey White
df972eeb05 QL: Merge branch 'main' into use-set-literal 2021-10-14 13:55:40 +01:00
Mathias Vorreiter Pedersen
78caab4214 Merge pull request #81 from github/doc-style
Add some queries for qldoc style
2021-10-14 13:46:48 +01:00
Mathias Vorreiter Pedersen
1762394b9b QL: Merge pull request #81 from github/doc-style
Add some queries for qldoc style
2021-10-14 13:46:48 +01:00
Mathias Vorreiter Pedersen
9a15feae29 Merge pull request #89 from github/esbena/proper-bundle
Attempt to use a proper query pack
2021-10-14 13:24:14 +01:00
Mathias Vorreiter Pedersen
4e73b9a30f QL: Merge pull request #89 from github/esbena/proper-bundle
Attempt to use a proper query pack
2021-10-14 13:24:14 +01:00
Esben Sparre Andreasen
a64660aae1 build a query pack separately, with a compilation cache 2021-10-14 14:09:01 +02:00
Esben Sparre Andreasen
aeabe67812 QL: build a query pack separately, with a compilation cache 2021-10-14 14:09:01 +02:00
Anders Schack-Mulligen
d7fd1e0718 Merge pull request #80 from github/aschackmull/calltarget-astnode
Refactor Call.getTarget to be an AstNode
2021-10-14 13:35:50 +02:00
Anders Schack-Mulligen
9a500eecb9 QL: Merge pull request #80 from github/aschackmull/calltarget-astnode
Refactor Call.getTarget to be an AstNode
2021-10-14 13:35:50 +02:00
Anders Schack-Mulligen
c0f1d365ba This is slightly faster without magic. 2021-10-14 13:12:26 +02:00
Anders Schack-Mulligen
dfa6f285e5 QL: This is slightly faster without magic. 2021-10-14 13:12:26 +02:00
Anders Schack-Mulligen
cd3839f621 Fix semantic merge conflict 2021-10-14 13:12:11 +02:00
Anders Schack-Mulligen
63b844856d QL: Fix semantic merge conflict 2021-10-14 13:12:11 +02:00
Joe Farebrother
b4a05804fa Also allow deprecated headers 2021-10-14 12:09:19 +01:00
Joe Farebrother
97db13beb4 QL: Also allow deprecated headers 2021-10-14 12:09:19 +01:00
Joe Farebrother
0f71066aaa Allow comments preceded by INTERNAL 2021-10-14 12:09:19 +01:00
Joe Farebrother
896eca684e QL: Allow comments preceded by INTERNAL 2021-10-14 12:09:19 +01:00
Joe Farebrother
fd3c53da9b Add query for class docs that don't start with an article.
Returns quite a few results, many of which seem to be TPs.
2021-10-14 12:09:18 +01:00
Joe Farebrother
f872ed13e3 QL: Add query for class docs that don't start with an article.
Returns quite a few results, many of which seem to be TPs.
2021-10-14 12:09:18 +01:00
Joe Farebrother
323ccc8cea Add query to find non US spelling 2021-10-14 12:09:18 +01:00
Joe Farebrother
4cb4073dd7 QL: Add query to find non US spelling 2021-10-14 12:09:18 +01:00
Anders Schack-Mulligen
350620d44a Fix bad magic. 2021-10-14 13:07:53 +02:00
Anders Schack-Mulligen
220f4b373c QL: Fix bad magic. 2021-10-14 13:07:53 +02:00
Anders Schack-Mulligen
6b4dbc3fe5 Fix compile error. 2021-10-14 13:07:53 +02:00
Anders Schack-Mulligen
2c01b54a49 QL: Fix compile error. 2021-10-14 13:07:53 +02:00
Anders Schack-Mulligen
ff3aba0f5d Adjust expected output. 2021-10-14 13:07:53 +02:00
Anders Schack-Mulligen
862706f709 QL: Adjust expected output. 2021-10-14 13:07:53 +02:00
Anders Schack-Mulligen
ffc25f8f89 Fix semantic merge conflict. 2021-10-14 13:06:41 +02:00
Anders Schack-Mulligen
744c3447c9 QL: Fix semantic merge conflict. 2021-10-14 13:06:41 +02:00
Anders Schack-Mulligen
41a0bf154f Move some AstNodes to Ast.qll, fix compilation error. 2021-10-14 13:06:41 +02:00
Anders Schack-Mulligen
946968b37c QL: Move some AstNodes to Ast.qll, fix compilation error. 2021-10-14 13:06:41 +02:00
Anders Schack-Mulligen
7955a8b6c8 Refactor 2021-10-14 13:06:41 +02:00
Anders Schack-Mulligen
69cf373f21 QL: Refactor 2021-10-14 13:06:41 +02:00
Mathias Vorreiter Pedersen
3d0917e6fc Merge pull request #96 from github/erik-krogh/dont-use-getaqlclass
add query to detect uses of getAQlClass
2021-10-14 12:06:00 +01:00
Mathias Vorreiter Pedersen
09d727f343 QL: Merge pull request #96 from github/erik-krogh/dont-use-getaqlclass
add query to detect uses of getAQlClass
2021-10-14 12:06:00 +01:00
Erik Krogh Kristensen
6af27c23ec lowercase query id 2021-10-14 12:59:27 +02:00
Erik Krogh Kristensen
5fc1b8bb29 QL: lowercase query id 2021-10-14 12:59:27 +02:00
Erik Krogh Kristensen
949ead913f add query to detect uses of getAQlClass 2021-10-14 12:59:27 +02:00
Erik Krogh Kristensen
e167554ad9 QL: add query to detect uses of getAQlClass 2021-10-14 12:59:27 +02:00
Mathias Vorreiter Pedersen
486fc453e7 Merge pull request #99 from github/missing-noinline
Add query: Missing `noinline`
2021-10-14 11:37:16 +01:00
Mathias Vorreiter Pedersen
b46dfc076d QL: Merge pull request #99 from github/missing-noinline
Add query: Missing `noinline`
2021-10-14 11:37:16 +01:00
Mathias Vorreiter Pedersen
626ec4d209 QL: Accept test changes. 2021-10-14 11:28:40 +01:00
Mathias Vorreiter Pedersen
7bcc906d67 QL: QL: Accept test changes. 2021-10-14 11:28:40 +01:00
Mathias Vorreiter Pedersen
3e3ad8e5d4 Merge branch 'main' into missing-noinline 2021-10-14 11:08:05 +01:00
Mathias Vorreiter Pedersen
d4b9c36343 QL: Merge branch 'main' into missing-noinline 2021-10-14 11:08:05 +01:00
Mathias Vorreiter Pedersen
deffeff01c Merge pull request #97 from github/fix-spurious-exists-mistakes
QL: Respond to PR reviews for #87
2021-10-14 11:03:36 +01:00
Mathias Vorreiter Pedersen
8e1494b91a QL: Merge pull request #97 from github/fix-spurious-exists-mistakes
QL: Respond to PR reviews for #87
2021-10-14 11:03:36 +01:00
Mathias Vorreiter Pedersen
2f7272d1ed QL: Add a query that finds missing noinline or nomagic annotations. 2021-10-14 11:00:26 +01:00
Mathias Vorreiter Pedersen
f4d35f6afe QL: QL: Add a query that finds missing noinline or nomagic annotations. 2021-10-14 11:00:26 +01:00
Mathias Vorreiter Pedersen
c900118731 QL: Model QL annotations. 2021-10-14 10:59:25 +01:00
Mathias Vorreiter Pedersen
c9bfd85c0d QL: QL: Model QL annotations. 2021-10-14 10:59:25 +01:00
Joe Farebrother
9749f797c8 Merge pull request #70 from github/dont-mention-this
Query to find member predicates that don't depend on `this`
2021-10-14 10:49:49 +01:00
Joe Farebrother
ed87d77bc5 QL: Merge pull request #70 from github/dont-mention-this
Query to find member predicates that don't depend on `this`
2021-10-14 10:49:49 +01:00
Mathias Vorreiter Pedersen
ed5960e015 QL: Respond to PR reviews. 2021-10-14 10:48:54 +01:00
Mathias Vorreiter Pedersen
4406065807 QL: QL: Respond to PR reviews. 2021-10-14 10:48:54 +01:00
Mathias Vorreiter Pedersen
7d9c408af4 Merge pull request #87 from github/mathiasvp/superfluous-exists
New query: Unnecessary 'exists'
2021-10-14 10:23:53 +01:00
Mathias Vorreiter Pedersen
dd6abdc06b QL: Merge pull request #87 from github/mathiasvp/superfluous-exists
New query: Unnecessary 'exists'
2021-10-14 10:23:53 +01:00
Taus
5a519c5089 Add test for override
This test demonstrates that our handling of `override` is incorrect.

Quick-eval'ing the `test` predicate produces the following output:

| f |  i  |  j  |
+---+-----+-----+
| 1 |  10 |  10 |
| 1 |  10 | 100 |
| 1 | 100 |  10 |
| 1 | 100 | 100 |
| 2 |  20 |  20 |
| 3 |   3 |   3 |

this demonstrates that `f.bar` and `f.baz` can resolve to all predicates
of that name in the file.

However, at present we only capture the calls to members on `Foo`.
2021-10-14 09:14:59 +00:00
Taus
b5bef24ce2 QL: Add test for override
This test demonstrates that our handling of `override` is incorrect.

Quick-eval'ing the `test` predicate produces the following output:

| f |  i  |  j  |
+---+-----+-----+
| 1 |  10 |  10 |
| 1 |  10 | 100 |
| 1 | 100 |  10 |
| 1 | 100 | 100 |
| 2 |  20 |  20 |
| 3 |   3 |   3 |

this demonstrates that `f.bar` and `f.baz` can resolve to all predicates
of that name in the file.

However, at present we only capture the calls to members on `Foo`.
2021-10-14 09:14:59 +00:00
Erik Krogh Kristensen
f7ff83c2e7 Merge pull request #93 from github/aschackmull/delete-vscode-file
Delete this file that vscode keeps changing for me.
2021-10-14 11:01:33 +02:00
Erik Krogh Kristensen
fb491c392e QL: Merge pull request #93 from github/aschackmull/delete-vscode-file
Delete this file that vscode keeps changing for me.
2021-10-14 11:01:33 +02:00
Anders Schack-Mulligen
11fd4f4997 Delete this file that vscode keeps changing for me. 2021-10-14 10:59:39 +02:00
Anders Schack-Mulligen
56d9c351d5 QL: Delete this file that vscode keeps changing for me. 2021-10-14 10:59:39 +02:00
Mathias Vorreiter Pedersen
bff9665866 Merge branch 'main' into mathiasvp/superfluous-exists 2021-10-14 09:49:40 +01:00
Mathias Vorreiter Pedersen
1762b4fb91 QL: Merge branch 'main' into mathiasvp/superfluous-exists 2021-10-14 09:49:40 +01:00
Taus
f0a8c77095 Merge pull request #91 from github/tausbn/fix-parsing-of-unique
Fix parsing of `unique`
2021-10-14 10:21:49 +02:00
Taus
2cedddfce8 QL: Merge pull request #91 from github/tausbn/fix-parsing-of-unique
Fix parsing of `unique`
2021-10-14 10:21:49 +02:00
Taus
a5fcc5c15a Fix parsing of unique 2021-10-14 08:09:13 +00:00
Taus
5d975089c1 QL: Fix parsing of unique 2021-10-14 08:09:13 +00:00
Mathias Vorreiter Pedersen
455a34a1ec Merge pull request #77 from github/erik-krogh/qlpacks
add pretty AST for YAML and a QLPack utility class
2021-10-14 08:42:52 +01:00
Mathias Vorreiter Pedersen
18c427cddc QL: Merge pull request #77 from github/erik-krogh/qlpacks
add pretty AST for YAML and a QLPack utility class
2021-10-14 08:42:52 +01:00
Mathias Vorreiter Pedersen
e46ccc072e Merge pull request #82 from github/esbena/codeql-action-on-other-repos 2021-10-14 07:44:15 +01:00
Mathias Vorreiter Pedersen
238fba9b6e QL: Merge pull request #82 from github/esbena/codeql-action-on-other-repos 2021-10-14 07:44:15 +01:00
Esben Sparre Andreasen
0ff2de9b5e restrict the queries that are run by default 2021-10-14 08:12:04 +02:00
Esben Sparre Andreasen
b0cbb31895 QL: restrict the queries that are run by default 2021-10-14 08:12:04 +02:00
Esben Sparre Andreasen
98b359bd9a Add codeql-go sources (abe3f2148b) 2021-10-14 08:09:51 +02:00
Esben Sparre Andreasen
3039206eab QL: Add codeql-go sources (abe3f2148b) 2021-10-14 08:09:51 +02:00
Esben Sparre Andreasen
53e17e7835 Add codeql sources (a2371370ff) 2021-10-14 08:09:51 +02:00
Esben Sparre Andreasen
808fd78d96 QL: Add codeql sources (a2371370ff) 2021-10-14 08:09:51 +02:00
Esben Sparre Andreasen
9826e7df1d Add codeql-ruby sources (236643fc43) 2021-10-14 08:09:50 +02:00
Esben Sparre Andreasen
946c572413 QL: Add codeql-ruby sources (236643fc43) 2021-10-14 08:09:50 +02:00
Esben Sparre Andreasen
d9f38826f7 Implement import-repositories.sh 2021-10-14 08:09:50 +02:00
Esben Sparre Andreasen
d8e1e3e8c0 QL: Implement import-repositories.sh 2021-10-14 08:09:50 +02:00
Mathias Vorreiter Pedersen
c5bcb7999e QL: Complete the GVN library. 2021-10-13 22:48:45 +01:00
Mathias Vorreiter Pedersen
c21df48bcd QL: QL: Complete the GVN library. 2021-10-13 22:48:45 +01:00
Erik Krogh Kristensen
5e7adc661f autoformat 2021-10-13 20:26:40 +02:00
Erik Krogh Kristensen
4958b8ba0d QL: autoformat 2021-10-13 20:26:40 +02:00
Mathias Vorreiter Pedersen
5b881c2151 Merge pull request #73 from github/tausbn/add-implicit-this-query
Add "implicit `this`" query
2021-10-13 17:36:02 +01:00
Mathias Vorreiter Pedersen
ce3a531daf QL: Merge pull request #73 from github/tausbn/add-implicit-this-query
Add "implicit `this`" query
2021-10-13 17:36:02 +01:00
Mathias Vorreiter Pedersen
c3141125af QL: Add a query that finds unnecessary 'exists'. 2021-10-13 17:31:29 +01:00
Mathias Vorreiter Pedersen
a917f240cf QL: QL: Add a query that finds unnecessary 'exists'. 2021-10-13 17:31:29 +01:00
Mathias Vorreiter Pedersen
2543b720e6 QL: Add a basic GVN library. 2021-10-13 17:26:26 +01:00
Mathias Vorreiter Pedersen
690b7ef617 QL: QL: Add a basic GVN library. 2021-10-13 17:26:26 +01:00
Mathias Vorreiter Pedersen
c577817882 QL: Add some convenience predicates in 'Ast.qll' and move a couple of the predicates from subclasses of 'BinOpExpr' into 'BinOpExpr'. 2021-10-13 17:26:00 +01:00
Mathias Vorreiter Pedersen
4795cbb849 QL: QL: Add some convenience predicates in 'Ast.qll' and move a couple of the predicates from subclasses of 'BinOpExpr' into 'BinOpExpr'. 2021-10-13 17:26:00 +01:00
Mathias Vorreiter Pedersen
4c4fd52347 QL: Add some more model classes that represent builtin QL classes. 2021-10-13 17:24:27 +01:00
Mathias Vorreiter Pedersen
d7f08703af QL: QL: Add some more model classes that represent builtin QL classes. 2021-10-13 17:24:27 +01:00
Erik Krogh Kristensen
31394878a2 resolve calls to db relations 2021-10-13 17:03:24 +02:00
Erik Krogh Kristensen
b31f705ffc QL: resolve calls to db relations 2021-10-13 17:03:24 +02:00
Taus
06ba078ef2 Merge pull request #83 from github/tausbn/fix-missing-override-fps
Fix "missing override" FPs
2021-10-13 16:36:18 +02:00
Taus
823c24a7ab QL: Merge pull request #83 from github/tausbn/fix-missing-override-fps
Fix "missing override" FPs
2021-10-13 16:36:18 +02:00
Erik Krogh Kristensen
1a1770fc06 resolve imports across qlpacks 2021-10-13 16:20:07 +02:00
Erik Krogh Kristensen
bc74af7307 QL: resolve imports across qlpacks 2021-10-13 16:20:07 +02:00
Taus
bd01d92500 Fix "missing override" FPs
This brings the analysis back to the level it was at before the addition
of `instanceof`.
2021-10-13 14:07:24 +00:00
Taus
cc43230244 QL: Fix "missing override" FPs
This brings the analysis back to the level it was at before the addition
of `instanceof`.
2021-10-13 14:07:24 +00:00
Geoffrey White
0704ab7bd3 Add tests. 2021-10-13 15:00:54 +01:00
Geoffrey White
7c02b6a3b2 QL: Add tests. 2021-10-13 15:00:54 +01:00
Geoffrey White
c8c23a6eb4 Support hasName(x) pattern as well. 2021-10-13 15:00:54 +01:00
Geoffrey White
161461eb6f QL: Support hasName(x) pattern as well. 2021-10-13 15:00:54 +01:00
Geoffrey White
e6242fd349 Add ql/use-set-literal query. 2021-10-13 15:00:54 +01:00
Geoffrey White
d933bf6f24 QL: Add ql/use-set-literal query. 2021-10-13 15:00:54 +01:00
Anders Schack-Mulligen
dd4f6edd62 Merge pull request #75 from github/aschackmull/isclosure
Expose transitive closure syntax.
2021-10-13 15:45:20 +02:00
Anders Schack-Mulligen
4b73c99c56 QL: Merge pull request #75 from github/aschackmull/isclosure
Expose transitive closure syntax.
2021-10-13 15:45:20 +02:00
Mathias Vorreiter Pedersen
43b1185d82 Merge pull request #79 from github/esbena/fix-1
fix getAPrimaryQlClass: SuperAccess -> Super
2021-10-13 14:44:25 +01:00
Mathias Vorreiter Pedersen
366fc23938 QL: Merge pull request #79 from github/esbena/fix-1
fix getAPrimaryQlClass: SuperAccess -> Super
2021-10-13 14:44:25 +01:00
Esben Sparre Andreasen
3e7b82a02a fix getAPrimaryQlClass: SuperAccess -> Super 2021-10-13 15:38:16 +02:00
Esben Sparre Andreasen
64a3ffdca7 QL: fix getAPrimaryQlClass: SuperAccess -> Super 2021-10-13 15:38:16 +02:00
Erik Krogh Kristensen
06f2345bbb add pretty AST for YAML and a QLPack utility class 2021-10-13 15:35:14 +02:00
Erik Krogh Kristensen
236989f6fd QL: add pretty AST for YAML and a QLPack utility class 2021-10-13 15:35:14 +02:00
Mathias Vorreiter Pedersen
aef394e2d1 Merge pull request #62 from github/if-with-none
QL: Add query that finds 'if p() then q() else none()'
2021-10-13 14:29:15 +01:00
Mathias Vorreiter Pedersen
d2222ee9f2 QL: Merge pull request #62 from github/if-with-none
QL: Add query that finds 'if p() then q() else none()'
2021-10-13 14:29:15 +01:00
Esben Sparre Andreasen
b8d26abbc2 Merge pull request #64 from github/esbena/codeql-action-support
CodeQL-action to work with QL-for-QL
2021-10-13 15:24:13 +02:00
Esben Sparre Andreasen
d41331b28b QL: Merge pull request #64 from github/esbena/codeql-action-support
CodeQL-action to work with QL-for-QL
2021-10-13 15:24:13 +02:00
Esben Sparre Andreasen
85a35544af add workflow with codeql-action 2021-10-13 15:21:08 +02:00
Esben Sparre Andreasen
5e1f565b6a QL: add workflow with codeql-action 2021-10-13 15:21:08 +02:00
Taus
e524076045 Extend the tests slightly
Adds a test for when the call is to an outer, non-member predicate.
2021-10-13 13:03:30 +00:00
Taus
d0cb1384a9 QL: Extend the tests slightly
Adds a test for when the call is to an outer, non-member predicate.
2021-10-13 13:03:30 +00:00
Anders Schack-Mulligen
94dbf2b7b4 Expose transitive closure syntax. 2021-10-13 12:48:38 +00:00
Anders Schack-Mulligen
7d68020c7b QL: Expose transitive closure syntax. 2021-10-13 12:48:38 +00:00
Taus
bc5e0924d2 Add tests for "implicit this" 2021-10-13 12:27:20 +00:00
Taus
a0e2bd57a7 QL: Add tests for "implicit this" 2021-10-13 12:27:20 +00:00
Taus
48cfa9665a Add "implicit this" query 2021-10-13 12:08:19 +00:00
Taus
fb5513c1c8 QL: Add "implicit this" query 2021-10-13 12:08:19 +00:00
Mathias Vorreiter Pedersen
95ea619cc4 Merge pull request #69 from github/erik-krogh/perf
fix two bad join orders
2021-10-13 12:53:12 +01:00
Mathias Vorreiter Pedersen
d1721d0bcd QL: Merge pull request #69 from github/erik-krogh/perf
fix two bad join orders
2021-10-13 12:53:12 +01:00
Taus
2d412d63e0 Merge pull request #71 from github/tausbn/more-yaml-hacking
"Parse" YAML without errors
2021-10-13 13:51:20 +02:00
Taus
411faca6ef QL: Merge pull request #71 from github/tausbn/more-yaml-hacking
"Parse" YAML without errors
2021-10-13 13:51:20 +02:00
Geoffrey White
3dab87e6ca Merge pull request #48 from github/extractor-pack
Make the create-extractor-pack.ps1 script more reliable.
2021-10-13 12:38:10 +01:00
Geoffrey White
ca81110e4b QL: Merge pull request #48 from github/extractor-pack
Make the create-extractor-pack.ps1 script more reliable.
2021-10-13 12:38:10 +01:00
Erik Krogh Kristensen
4cb004c0c6 autoformat 2021-10-13 13:34:47 +02:00
Erik Krogh Kristensen
15679dfec6 QL: autoformat 2021-10-13 13:34:47 +02:00
Erik Krogh Kristensen
705e24690f cache getClassPredicate 2021-10-13 13:26:37 +02:00
Erik Krogh Kristensen
09862b9fe7 QL: cache getClassPredicate 2021-10-13 13:26:37 +02:00
Taus
7034933cee "Parse" YAML without errors 2021-10-13 11:24:26 +00:00
Taus
30040680ec QL: "Parse" YAML without errors 2021-10-13 11:24:26 +00:00
Joe Farebrother
1b4130fe97 Add check for predicates with an override annotation 2021-10-13 12:22:46 +01:00
Joe Farebrother
c3493d6fde QL: Add check for predicates with an override annotation 2021-10-13 12:22:46 +01:00
Erik Krogh Kristensen
584702058d fix two bad join orders 2021-10-13 13:20:41 +02:00
Erik Krogh Kristensen
932f00b43e QL: fix two bad join orders 2021-10-13 13:20:41 +02:00
Joe Farebrother
33bd267eb0 "doesn't mention this" query 2021-10-13 12:09:04 +01:00
Joe Farebrother
d474a76cf0 QL: "doesn't mention this" query 2021-10-13 12:09:04 +01:00
Anders Schack-Mulligen
1f6eb6e763 Merge pull request #55 from github/mathiasvp/prefix-or-suffix-in-comparison
New query: Find uses of '.prefix' or '.suffix' when comparing against string literals
2021-10-13 12:45:12 +02:00
Anders Schack-Mulligen
3ed7f9664c QL: Merge pull request #55 from github/mathiasvp/prefix-or-suffix-in-comparison
New query: Find uses of '.prefix' or '.suffix' when comparing against string literals
2021-10-13 12:45:12 +02:00
Anders Schack-Mulligen
35f6c598e7 Merge pull request #54 from github/aschackmull/singleton-set
New query: Singleton set literal.
2021-10-13 12:43:41 +02:00
Anders Schack-Mulligen
87910e80af QL: Merge pull request #54 from github/aschackmull/singleton-set
New query: Singleton set literal.
2021-10-13 12:43:41 +02:00
Geoffrey White
ddc7794c8d Merge branch 'main' into extractor-pack 2021-10-13 11:40:26 +01:00
Geoffrey White
1265c3fbed QL: Merge branch 'main' into extractor-pack 2021-10-13 11:40:26 +01:00
Philip Ginsbach
14fae833cb Merge pull request #65 from github/ginsbach/SuggestInstanceof
Suggest instanceof extensions
2021-10-13 11:33:41 +01:00
Philip Ginsbach
fed3d80a3d QL: Merge pull request #65 from github/ginsbach/SuggestInstanceof
Suggest instanceof extensions
2021-10-13 11:33:41 +01:00
Erik Krogh Kristensen
88c003681b Merge pull request #61 from github/aschackmull/extends-formula
Add missing extends Formula
2021-10-13 12:33:29 +02:00
Erik Krogh Kristensen
6b901429d0 QL: Merge pull request #61 from github/aschackmull/extends-formula
Add missing extends Formula
2021-10-13 12:33:29 +02:00
Erik Krogh Kristensen
6e274f640f Merge pull request #63 from github/erik-krogh/disable-windows
disable windows CI
2021-10-13 12:28:13 +02:00
Erik Krogh Kristensen
0060fcbfd7 QL: Merge pull request #63 from github/erik-krogh/disable-windows
disable windows CI
2021-10-13 12:28:13 +02:00
Erik Krogh Kristensen
79c51625a8 disable windows part 3 2021-10-13 12:10:02 +02:00
Erik Krogh Kristensen
42bf00f17e QL: disable windows part 3 2021-10-13 12:10:02 +02:00
Philip Ginsbach
754bf84abe suggest replacing 'this instanceof ...' in constructor with non-extending subtypes 2021-10-13 11:06:59 +01:00
Philip Ginsbach
9ae0aad46d QL: suggest replacing 'this instanceof ...' in constructor with non-extending subtypes 2021-10-13 11:06:59 +01:00
Erik Krogh Kristensen
256af31b38 disable windows part 2 2021-10-13 12:05:17 +02:00
Erik Krogh Kristensen
bd6825833d QL: disable windows part 2 2021-10-13 12:05:17 +02:00
Mathias Vorreiter Pedersen
af3ae3f1fa QL: Respond to PR comments. 2021-10-13 09:57:05 +00:00
Mathias Vorreiter Pedersen
df20f84ae2 QL: QL: Respond to PR comments. 2021-10-13 09:57:05 +00:00
Erik Krogh Kristensen
825c1c4407 disable windows CI 2021-10-13 11:54:03 +02:00
Erik Krogh Kristensen
9b36fdf9bd QL: disable windows CI 2021-10-13 11:54:03 +02:00
Mathias Vorreiter Pedersen
c3f9d584a4 QL: Add query that finds 'if p() then q() else none()'. 2021-10-13 09:48:57 +00:00
Mathias Vorreiter Pedersen
6c7d848727 QL: QL: Add query that finds 'if p() then q() else none()'. 2021-10-13 09:48:57 +00:00
Anders Schack-Mulligen
7bd0bf9908 Add missing extends Formula 2021-10-13 09:47:10 +00:00
Anders Schack-Mulligen
01ef4d7060 QL: Add missing extends Formula 2021-10-13 09:47:10 +00:00
Mathias Vorreiter Pedersen
81e88f8d34 QL: Actually use the SuffixPredicateCall class as well. Now the query finds 20 results. 2021-10-13 09:31:45 +00:00
Mathias Vorreiter Pedersen
e927c43222 QL: QL: Actually use the SuffixPredicateCall class as well. Now the query finds 20 results. 2021-10-13 09:31:45 +00:00
Mathias Vorreiter Pedersen
812597505d QL: Respond to PR reviews. 2021-10-13 09:28:02 +00:00
Mathias Vorreiter Pedersen
b4d710d58f QL: QL: Respond to PR reviews. 2021-10-13 09:28:02 +00:00
Geoffrey White
d99d02994a Update README.md
I needed the rust-analyzer extension to get anywhere in VSCode.
2021-10-13 10:09:08 +01:00
Geoffrey White
46789aecaa QL: Update README.md
I needed the rust-analyzer extension to get anywhere in VSCode.
2021-10-13 10:09:08 +01:00
Mathias Vorreiter Pedersen
6c55a67f9a QL: Add query to find uses of .prefix or .suffix when comparing against literals. 2021-10-13 09:06:58 +00:00
Mathias Vorreiter Pedersen
f86a827bb6 QL: QL: Add query to find uses of .prefix or .suffix when comparing against literals. 2021-10-13 09:06:58 +00:00
Anders Schack-Mulligen
79485ec5da New query: Singleton set literal. 2021-10-13 09:01:54 +00:00
Anders Schack-Mulligen
f71acdf9fe QL: New query: Singleton set literal. 2021-10-13 09:01:54 +00:00
Erik Krogh Kristensen
ed767b4a54 Merge pull request #51 from github/aschackmull/ignore-work
Add work folder to gitignore.
2021-10-13 10:52:49 +02:00
Erik Krogh Kristensen
eb527a5494 QL: Merge pull request #51 from github/aschackmull/ignore-work
Add work folder to gitignore.
2021-10-13 10:52:49 +02:00
Anders Schack-Mulligen
f71881ef78 Add work folder to gitignore. 2021-10-13 08:28:27 +00:00
Anders Schack-Mulligen
a8b1ef83f1 QL: Add work folder to gitignore. 2021-10-13 08:28:27 +00:00
Geoffrey White
76144a7f7d Make the create-extractor-pack.ps1 script more reliable. 2021-10-13 09:17:59 +01:00
Geoffrey White
54b7fa3944 QL: Make the create-extractor-pack.ps1 script more reliable. 2021-10-13 09:17:59 +01:00
Taus
ef538570c8 Merge pull request #37 from github/toUnicodeBuildin
add `toUnicode` as a build-in
2021-10-13 10:13:05 +02:00
Taus
352c50c2e5 QL: Merge pull request #37 from github/toUnicodeBuildin
add `toUnicode` as a build-in
2021-10-13 10:13:05 +02:00
Erik Krogh Kristensen
bb3e6399a4 Merge pull request #41 from github/tausbn/support-instanceof
Support `instanceof`
2021-10-13 09:14:02 +02:00
Erik Krogh Kristensen
fbb58f1954 QL: Merge pull request #41 from github/tausbn/support-instanceof
Support `instanceof`
2021-10-13 09:14:02 +02:00
Taus
8c6d139d67 Fix up getASuperType
I'm not sure if it's correct to include also the `instanceof`s, but we
can always fix this later.
2021-10-12 19:28:13 +00:00
Taus
db6551c22d QL: Fix up getASuperType
I'm not sure if it's correct to include also the `instanceof`s, but we
can always fix this later.
2021-10-12 19:28:13 +00:00
Taus
d436be7e96 Support instanceof
Stills needs to be hooked up correctly to the AST.
2021-10-12 17:40:29 +00:00
Taus
4694ab4773 QL: Support instanceof
Stills needs to be hooked up correctly to the AST.
2021-10-12 17:40:29 +00:00
Erik Krogh Kristensen
7b61445f83 Merge pull request #40 from github/erik-krogh/fix-qltest
fix qlpack version string
2021-10-12 13:08:40 +02:00
Erik Krogh Kristensen
ca21f5800b QL: Merge pull request #40 from github/erik-krogh/fix-qltest
fix qlpack version string
2021-10-12 13:08:40 +02:00
Erik Krogh Kristensen
b0a237bcc1 fix qlpack version string 2021-10-12 11:01:18 +00:00
Erik Krogh Kristensen
d6d626e932 QL: fix qlpack version string 2021-10-12 11:01:18 +00:00
Taus
9b1836e366 Merge pull request #36 from github/various-small-fixes
Various small fixes
2021-09-23 13:42:19 +02:00
Taus
b719faa627 QL: Merge pull request #36 from github/various-small-fixes
Various small fixes
2021-09-23 13:42:19 +02:00
Erik Krogh Kristensen
ba40a99ef8 Merge pull request #38 from github/rankOne
add a query for finding rank[1]
2021-08-18 23:23:00 +02:00
Erik Krogh Kristensen
b8a368a47f QL: Merge pull request #38 from github/rankOne
add a query for finding rank[1]
2021-08-18 23:23:00 +02:00
Erik Krogh Kristensen
91b8c1c4a0 Update ql/src/queries/style/RankOne.ql
Co-authored-by: Taus <tausbn@github.com>
2021-08-18 11:25:36 +02:00
Erik Krogh Kristensen
23b2d43440 QL: Update ql/src/queries/style/RankOne.ql
Co-authored-by: Taus <tausbn@github.com>
2021-08-18 11:25:36 +02:00
Erik Krogh Kristensen
feb1ab86f0 add a query for finding rank[1] 2021-08-18 09:19:05 +00:00
Erik Krogh Kristensen
b45a793e28 QL: add a query for finding rank[1] 2021-08-18 09:19:05 +00:00
Erik Krogh Kristensen
23e3062c3b add toUnicode as a build-in 2021-06-22 12:07:47 +00:00
Erik Krogh Kristensen
b385dfd5a8 QL: add toUnicode as a build-in 2021-06-22 12:07:47 +00:00
Taus
e79ded9046 Add exclusions to Module consistency test 2021-06-19 12:41:16 +00:00
Taus
2515fc0ebc QL: Add exclusions to Module consistency test 2021-06-19 12:41:16 +00:00
Taus
6d1dc24fa7 Autoformat 2021-06-19 12:36:10 +00:00
Taus
7a117caaea QL: Autoformat 2021-06-19 12:36:10 +00:00
Taus
6bff0f48a2 Remove SuperAccess::getType()
This had a bad effect on our call resolution, so I'm reverting it for
now. We may want to diverge from the language specification here.
2021-06-19 12:17:17 +00:00
Taus
2fa4424f71 QL: Remove SuperAccess::getType()
This had a bad effect on our call resolution, so I'm reverting it for
now. We may want to diverge from the language specification here.
2021-06-19 12:17:17 +00:00
Taus
b9238ea436 Update printAst test
to reflect the renaming of `Aggregate` to `FullAggregate`.
2021-06-19 12:16:42 +00:00
Taus
4c4a2658fe QL: Update printAst test
to reflect the renaming of `Aggregate` to `FullAggregate`.
2021-06-19 12:16:42 +00:00
Taus
e3a4d3074c Exclude a few more paths from tests 2021-06-19 11:54:50 +00:00
Taus
fb8f549d93 QL: Exclude a few more paths from tests 2021-06-19 11:54:50 +00:00
Taus
815337dde1 Split up Aggregate properly
Previously, we had `Aggregate` and `ExprAggregate` as separate classes,
the latter of which representing aggregates that contain only an
expression.

This was a problem for the `rank` aggregate, as it inherited from
`Aggregate`, but _could_ also contain just an expression (even if this
is rather rare).

To fix this, I renamed `Aggregate` to `FullAggregate` (to make the
division clearer), and added a new type `Aggregate` that represents the
union of these two types. Now `Rank` can inherit from the new class
`Aggregate` and everything is dandy.
2021-06-19 11:50:50 +00:00
Taus
76b55c4a5a QL: Split up Aggregate properly
Previously, we had `Aggregate` and `ExprAggregate` as separate classes,
the latter of which representing aggregates that contain only an
expression.

This was a problem for the `rank` aggregate, as it inherited from
`Aggregate`, but _could_ also contain just an expression (even if this
is rather rare).

To fix this, I renamed `Aggregate` to `FullAggregate` (to make the
division clearer), and added a new type `Aggregate` that represents the
union of these two types. Now `Rank` can inherit from the new class
`Aggregate` and everything is dandy.
2021-06-19 11:50:50 +00:00
Taus
1e973f3681 Fix getType for aggregates
We were only including the `strict` variant of `count` and not any of
the other ones (spot the mistake!).

Also, `unique` was added as a recognised aggregate name.
2021-06-19 11:47:45 +00:00
Taus
8d17a95265 QL: Fix getType for aggregates
We were only including the `strict` variant of `count` and not any of
the other ones (spot the mistake!).

Also, `unique` was added as a recognised aggregate name.
2021-06-19 11:47:45 +00:00
Taus
0ff0aecb22 Add more getType overrides
Mainly adds ones for primitive types.

One peculiarity: the language specification states that the type of
`super` is the same as the type of `this`, and _not_ the type of
the superclass on which the method is actually accessed. This seems a
bit strange to me, so I thought I would highlight it specifically.

Also, I'm not entirely sure that the rules around type coercion for
the various binary operators are 100% correct.
2021-06-19 11:40:12 +00:00
Taus
602c9e720e QL: Add more getType overrides
Mainly adds ones for primitive types.

One peculiarity: the language specification states that the type of
`super` is the same as the type of `this`, and _not_ the type of
the superclass on which the method is actually accessed. This seems a
bit strange to me, so I thought I would highlight it specifically.

Also, I'm not entirely sure that the rules around type coercion for
the various binary operators are 100% correct.
2021-06-19 11:40:12 +00:00
Taus
bc2932383b Merge pull request #35 from github/downstream-latest-generator 2021-06-02 10:07:09 +02:00
Taus
08dd9477c2 QL: Merge pull request #35 from github/downstream-latest-generator 2021-06-02 10:07:09 +02:00
Taus
35dccb5f3d Update to latest generator
Includes better QLDoc generation and better escaping in the generated
files (the latter has changed the dbscheme, so rebuilding databases will
be required).
2021-06-01 16:43:11 +00:00
Taus
75a959389c QL: Update to latest generator
Includes better QLDoc generation and better escaping in the generated
files (the latter has changed the dbscheme, so rebuilding databases will
be required).
2021-06-01 16:43:11 +00:00
Taus
c2ecad7ddb Merge pull request #34 from github/dbscheme-and-qlpack-support
Add support for dbscheme and qlpack.yml
2021-06-01 18:23:36 +02:00
Taus
22e4606358 QL: Merge pull request #34 from github/dbscheme-and-qlpack-support
Add support for dbscheme and qlpack.yml
2021-06-01 18:23:36 +02:00
Taus
9abe340a1f Fix getQLDoc compilation error 2021-05-31 08:55:27 +00:00
Taus
cbd0caa4ab QL: Fix getQLDoc compilation error 2021-05-31 08:55:27 +00:00
Taus
3cdc6a18ae Merge branch 'main' into dbscheme-and-qlpack-support 2021-05-31 10:50:39 +02:00
Taus
ada77a3c8b QL: Merge branch 'main' into dbscheme-and-qlpack-support 2021-05-31 10:50:39 +02:00
Taus
6b2c96615f Merge pull request #30 from github/qldoc-nodes
Add AST nodes for QLDoc
2021-05-31 10:45:15 +02:00
Taus
17ef056579 QL: Merge pull request #30 from github/qldoc-nodes
Add AST nodes for QLDoc
2021-05-31 10:45:15 +02:00
Taus
1cbcf40637 Simplify getAMember
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2021-05-31 10:26:50 +02:00
Taus
855683e980 QL: Simplify getAMember
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2021-05-31 10:26:50 +02:00
Erik Krogh Kristensen
4bbd06f51f improve performance of module resolution 2021-05-31 08:06:49 +00:00
Erik Krogh Kristensen
f2f6d34f21 QL: improve performance of module resolution 2021-05-31 08:06:49 +00:00
Erik Krogh Kristensen
b3e23bcc31 improve performance of type resolution 2021-05-31 07:51:11 +00:00
Erik Krogh Kristensen
3ee642868d QL: improve performance of type resolution 2021-05-31 07:51:11 +00:00
Erik Krogh Kristensen
a286dc349a improve scope resolution performance 2021-05-31 07:46:51 +00:00
Erik Krogh Kristensen
12627d19fa QL: improve scope resolution performance 2021-05-31 07:46:51 +00:00
Erik Krogh Kristensen
18b6216f78 more improvements to printAst performance 2021-05-31 07:33:11 +00:00
Erik Krogh Kristensen
7a4e4134da QL: more improvements to printAst performance 2021-05-31 07:33:11 +00:00
Erik Krogh Kristensen
7d4611941a fix printAst performance 2021-05-30 21:42:15 +00:00
Erik Krogh Kristensen
5e89bf99a8 QL: fix printAst performance 2021-05-30 21:42:15 +00:00
Erik Krogh Kristensen
a349fdd367 spaces in folder/file names are underscores in import names 2021-05-30 21:36:01 +00:00
Erik Krogh Kristensen
e47c4ff2ad QL: spaces in folder/file names are underscores in import names 2021-05-30 21:36:01 +00:00
Erik Krogh Kristensen
6c5e33e3d2 use qlpack existence to determine the root for imports 2021-05-30 21:30:11 +00:00
Erik Krogh Kristensen
1aa7cbb918 QL: use qlpack existence to determine the root for imports 2021-05-30 21:30:11 +00:00
Taus
4e8157e3cb Autoformat 2021-05-30 17:53:38 +00:00
Taus
676bc5ee2a QL: Autoformat 2021-05-30 17:53:38 +00:00
Taus
eaf6d8123d Add support for dbscheme and qlpack.yml
Currently the the YAML "parser" fails for some legacy files, but the
actual files appear to be parsed correctly.
2021-05-30 17:38:26 +00:00
Taus
2bbf1e37fc QL: Add support for dbscheme and qlpack.yml
Currently the the YAML "parser" fails for some legacy files, but the
actual files appear to be parsed correctly.
2021-05-30 17:38:26 +00:00
Erik Krogh Kristensen
5c80716724 Merge branch 'main' into qldoc-nodes 2021-05-30 15:51:29 +00:00
Erik Krogh Kristensen
01e420fd02 QL: Merge branch 'main' into qldoc-nodes 2021-05-30 15:51:29 +00:00
Erik Krogh Kristensen
33ed98e8b7 Merge pull request #32 from github/jumpToField
get jump to field to work
2021-05-29 22:09:44 +02:00
Erik Krogh Kristensen
63c7b21f4b QL: Merge pull request #32 from github/jumpToField
get jump to field to work
2021-05-29 22:09:44 +02:00
Erik Krogh Kristensen
c2c0a96f40 Merge pull request #33 from github/fixes
improve callgraph resolution, and other fixes
2021-05-29 22:09:32 +02:00
Erik Krogh Kristensen
35fe816918 QL: Merge pull request #33 from github/fixes
improve callgraph resolution, and other fixes
2021-05-29 22:09:32 +02:00
Erik Krogh Kristensen
48170f5ce0 change multipleResolveCall to ignore aliases 2021-05-29 19:30:40 +00:00
Erik Krogh Kristensen
f1aa5ef804 QL: change multipleResolveCall to ignore aliases 2021-05-29 19:30:40 +00:00
Erik Krogh Kristensen
bd86ffb35b fix the arity of predicate aliases 2021-05-29 19:23:58 +00:00
Erik Krogh Kristensen
5b1bab0921 QL: fix the arity of predicate aliases 2021-05-29 19:23:58 +00:00
Erik Krogh Kristensen
8dc3948221 support more types on aggregates 2021-05-29 19:23:58 +00:00
Erik Krogh Kristensen
7a33225fd0 QL: support more types on aggregates 2021-05-29 19:23:58 +00:00
Erik Krogh Kristensen
c8d0384907 add callgraph test 2021-05-29 19:23:58 +00:00
Erik Krogh Kristensen
04ca858e85 QL: add callgraph test 2021-05-29 19:23:58 +00:00
Erik Krogh Kristensen
068c57acdd add super calls to the callgraph 2021-05-29 19:23:58 +00:00
Erik Krogh Kristensen
c78bae69c8 QL: add super calls to the callgraph 2021-05-29 19:23:58 +00:00
Erik Krogh Kristensen
2d86b13d44 add super nodes 2021-05-29 19:23:58 +00:00
Erik Krogh Kristensen
aceab25d9b QL: add super nodes 2021-05-29 19:23:58 +00:00
Erik Krogh Kristensen
5dcc161f2d add getEnclosingPredicate utility predicate 2021-05-29 19:23:58 +00:00
Erik Krogh Kristensen
3d50a4d254 QL: add getEnclosingPredicate utility predicate 2021-05-29 19:23:58 +00:00
Erik Krogh Kristensen
fb50ba407d add test for boolean literals in the ast 2021-05-29 19:23:58 +00:00
Erik Krogh Kristensen
d9aa3bbdfa QL: add test for boolean literals in the ast 2021-05-29 19:23:58 +00:00
Erik Krogh Kristensen
8ad05b778d add support for boolean literals 2021-05-29 19:23:58 +00:00
Erik Krogh Kristensen
1ba51013a4 QL: add support for boolean literals 2021-05-29 19:23:58 +00:00
Taus
4140ce0f10 Fix misparse of -j - 1 2021-05-29 14:17:21 +00:00
Taus
bb418f9614 QL: Fix misparse of -j - 1 2021-05-29 14:17:21 +00:00
Taus
1345fa982a Merge pull request #31 from github/autogenerate-qldoc
Autogenerate QLDoc for `TreeSitter.qll`
2021-05-29 16:08:22 +02:00
Taus
3f2690c3b3 QL: Merge pull request #31 from github/autogenerate-qldoc
Autogenerate QLDoc for `TreeSitter.qll`
2021-05-29 16:08:22 +02:00
Taus
18fc76fdb8 Autoformat 2021-05-29 08:09:35 +00:00
Taus
aae4a1e3f9 QL: Autoformat 2021-05-29 08:09:35 +00:00
Taus
0b74535b4a Fix test output 2021-05-29 08:07:44 +00:00
Taus
1feb35efb7 QL: Fix test output 2021-05-29 08:07:44 +00:00
Taus
5658abd716 Merge branch 'main' into qldoc-nodes 2021-05-29 00:03:09 +02:00
Taus
4e060ce368 QL: Merge branch 'main' into qldoc-nodes 2021-05-29 00:03:09 +02:00
Taus
010bc39465 Fix tests
I'm not really a fan of `toString`s that don't indicate the type of the
object, so I added a reference to `getAPrimaryQlClass`. Hopefully this
should result in less noise in the diff.
2021-05-28 22:00:15 +00:00
Taus
23e4281ddb QL: Fix tests
I'm not really a fan of `toString`s that don't indicate the type of the
object, so I added a reference to `getAPrimaryQlClass`. Hopefully this
should result in less noise in the diff.
2021-05-28 22:00:15 +00:00
Erik Krogh Kristensen
7fa3645e5d get jump to field to work 2021-05-28 23:47:41 +02:00
Erik Krogh Kristensen
3cd7594247 QL: get jump to field to work 2021-05-28 23:47:41 +02:00
Taus
9b0b4df181 Add getAModule and getANewType
Also removes `getAQLDocComment`, as those were already dangling off of
their respective successors in the file (and so should not dangle off
of the top level as well).
2021-05-28 21:44:41 +00:00
Taus
109f938968 QL: Add getAModule and getANewType
Also removes `getAQLDocComment`, as those were already dangling off of
their respective successors in the file (and so should not dangle off
of the top level as well).
2021-05-28 21:44:41 +00:00
Taus
3280f02d6a Remove getAMember from getAChild
Adds `getAQLDocComment` for accessing those module members that are
simply QLDoc comments (apart from the one that applies to the module
itself, which is still accessed through `getQLDoc`.)
2021-05-28 21:12:02 +00:00
Taus
24230dc205 QL: Remove getAMember from getAChild
Adds `getAQLDocComment` for accessing those module members that are
simply QLDoc comments (apart from the one that applies to the module
itself, which is still accessed through `getQLDoc`.)
2021-05-28 21:12:02 +00:00
Taus
3a045ef4e5 Autogenerate QLDoc for TreeSitter.qll 2021-05-28 21:06:51 +00:00
Taus
7d597782b8 QL: Autogenerate QLDoc for TreeSitter.qll 2021-05-28 21:06:51 +00:00
shati-patel
e57f9e9a1b autoformat 2021-05-28 18:59:41 +01:00
shati-patel
1d4f6e0564 QL: autoformat 2021-05-28 18:59:41 +01:00
shati-patel
e401364fa1 fix space in test 2021-05-28 18:53:45 +01:00
shati-patel
03fcfdd53a QL: fix space in test 2021-05-28 18:53:45 +01:00
shati-patel
9e6b085e81 Link to hackathon issue from README 2021-05-28 18:38:12 +01:00
shati-patel
33fcfdef3d QL: Link to hackathon issue from README 2021-05-28 18:38:12 +01:00
shati-patel
dd598f8aa5 Add missing space 2021-05-28 18:36:40 +01:00
shati-patel
5a7f349bfa QL: Add missing space 2021-05-28 18:36:40 +01:00
Taus
64a53f8ba0 Add AST nodes for QLDoc 2021-05-28 17:11:02 +00:00
Taus
51fbee69c2 QL: Add AST nodes for QLDoc 2021-05-28 17:11:02 +00:00
Shati Patel
764a5d1457 Remove codeql-action placeholder file
(Didn't get code scanning set up, so this file doesn't do anything useful)
2021-05-28 18:03:13 +01:00
Shati Patel
64d24c744a QL: Remove codeql-action placeholder file
(Didn't get code scanning set up, so this file doesn't do anything useful)
2021-05-28 18:03:13 +01:00
Erik Krogh Kristensen
333e18a1da Merge pull request #29 from github/fourth-query
add `ql/override-parameter-name`
2021-05-28 18:00:48 +02:00
Erik Krogh Kristensen
2736b0149c QL: Merge pull request #29 from github/fourth-query
add `ql/override-parameter-name`
2021-05-28 18:00:48 +02:00
Erik Krogh Kristensen
fd8fd0b70e add ql/override-parameter-name 2021-05-28 14:59:44 +00:00
Erik Krogh Kristensen
775a0eebaa QL: add ql/override-parameter-name 2021-05-28 14:59:44 +00:00
Erik Krogh Kristensen
0c61c9d2b2 adjust qldoc on printAst 2021-05-28 14:35:01 +00:00
Erik Krogh Kristensen
fe6e7a8ed8 QL: adjust qldoc on printAst 2021-05-28 14:35:01 +00:00
Tom Hvitved
074ea79b9a Merge pull request #28 from github/caching
Cache some predicates
2021-05-28 15:25:12 +02:00
Tom Hvitved
5dec75abf3 QL: Merge pull request #28 from github/caching
Cache some predicates
2021-05-28 15:25:12 +02:00
Tom Hvitved
05d1788c1f Cache some predicates 2021-05-28 15:20:55 +02:00
Tom Hvitved
ce13360f9b QL: Cache some predicates 2021-05-28 15:20:55 +02:00
Tom Hvitved
42df07c23a Merge pull request #27 from github/newtype-call
Resolve `newtype` constructor calls
2021-05-28 15:14:52 +02:00
Tom Hvitved
27d0af917a QL: Merge pull request #27 from github/newtype-call
Resolve `newtype` constructor calls
2021-05-28 15:14:52 +02:00
Erik Krogh Kristensen
51230f6ee3 Merge pull request #25 from github/cleanup
cleanup
2021-05-28 15:07:16 +02:00
Erik Krogh Kristensen
7e69931455 QL: Merge pull request #25 from github/cleanup
cleanup
2021-05-28 15:07:16 +02:00
Tom Hvitved
8d245e6bc2 Resolve newtype constructor calls 2021-05-28 15:06:37 +02:00
Tom Hvitved
22cd2844d3 QL: Resolve newtype constructor calls 2021-05-28 15:06:37 +02:00
Erik Krogh Kristensen
f15ad39181 format 2021-05-28 13:02:01 +00:00
Erik Krogh Kristensen
3515580889 QL: format 2021-05-28 13:02:01 +00:00
Erik Krogh Kristensen
d171ace902 fix 2021-05-28 12:58:02 +00:00
Erik Krogh Kristensen
249d209f45 QL: fix 2021-05-28 12:58:02 +00:00
Erik Krogh Kristensen
c3344d0734 cleanup 2021-05-28 12:50:33 +00:00
Erik Krogh Kristensen
e456098a35 QL: cleanup 2021-05-28 12:50:33 +00:00
Taus
e89ed8a1f9 Reuse defined predicate arity 2021-05-28 12:40:45 +00:00
Taus
e62e72edfd QL: Reuse defined predicate arity 2021-05-28 12:40:45 +00:00
Taus
fa8efb6ca9 Make getParameter 0-indexed 2021-05-28 12:22:14 +00:00
Taus
45ae088fd8 QL: Make getParameter 0-indexed 2021-05-28 12:22:14 +00:00
Joe Farebrother
3f133a7e84 Merge pull request #26 from github/builtins
Built in predicates
2021-05-28 13:01:14 +01:00
Joe Farebrother
236f413e01 QL: Merge pull request #26 from github/builtins
Built in predicates
2021-05-28 13:01:14 +01:00
Joe Farebrother
3945dbfa54 Support builtin predicates 2021-05-28 12:57:36 +01:00
Joe Farebrother
87e39c7f23 QL: Support builtin predicates 2021-05-28 12:57:36 +01:00
Tom Hvitved
671628484b Merge pull request #24 from github/types
Resolve calls
2021-05-28 13:50:22 +02:00
Tom Hvitved
28d2daea3f QL: Merge pull request #24 from github/types
Resolve calls
2021-05-28 13:50:22 +02:00
Tom Hvitved
41a2e020bd Update expected test output 2021-05-28 13:49:31 +02:00
Tom Hvitved
17f6cad0e9 QL: Update expected test output 2021-05-28 13:49:31 +02:00
Tom Hvitved
5112b49b94 Remove compilation warnings 2021-05-28 13:44:31 +02:00
Tom Hvitved
4110810431 QL: Remove compilation warnings 2021-05-28 13:44:31 +02:00
Joe Farebrother
cee5dd0cba Merge pull request #20 from github/missing-override-query
Add Missing Override query
2021-05-28 12:40:17 +01:00
Joe Farebrother
c33e0a5f30 QL: Merge pull request #20 from github/missing-override-query
Add Missing Override query
2021-05-28 12:40:17 +01:00
Joe Farebrother
26d0e9df5d Add Missing Override query 2021-05-28 12:39:59 +01:00
Joe Farebrother
933593223f QL: Add Missing Override query 2021-05-28 12:39:59 +01:00
Tom Hvitved
5975ee4932 Resolve calls 2021-05-28 13:39:21 +02:00
Tom Hvitved
99a3a09033 QL: Resolve calls 2021-05-28 13:39:21 +02:00
Taus
ac35f348c4 printAst edge labels and a bit of consistency 2021-05-28 11:33:06 +00:00
Taus
f46dab6c84 QL: printAst edge labels and a bit of consistency 2021-05-28 11:33:06 +00:00
Taus
c8de28c0a0 Get rid of getParent overrides 2021-05-28 11:11:33 +00:00
Taus
d65e0a9181 QL: Get rid of getParent overrides 2021-05-28 11:11:33 +00:00
Tom Hvitved
535fd73cc9 Merge pull request #23 from github/as-expr
Only generate `AsExpr`s when there is an `as` keyword
2021-05-28 12:16:11 +02:00
Tom Hvitved
752194b19e QL: Merge pull request #23 from github/as-expr
Only generate `AsExpr`s when there is an `as` keyword
2021-05-28 12:16:11 +02:00
Tom Hvitved
cbcc4ead36 Only generate AsExprs when there is an as keyword 2021-05-28 12:12:34 +02:00
Tom Hvitved
bac0e02fae QL: Only generate AsExprs when there is an as keyword 2021-05-28 12:12:34 +02:00
Erik Krogh Kristensen
2e02e15875 Merge pull request #22 from github/third-query
add ql/rexexp-pattern
2021-05-28 12:00:32 +02:00
Erik Krogh Kristensen
f0bb846345 QL: Merge pull request #22 from github/third-query
add ql/rexexp-pattern
2021-05-28 12:00:32 +02:00
Erik Krogh Kristensen
9113469d9d add ql/rexexp-pattern 2021-05-28 09:55:09 +00:00
Erik Krogh Kristensen
de57b2bc9f QL: add ql/rexexp-pattern 2021-05-28 09:55:09 +00:00
Erik Krogh Kristensen
cc60ddde1c Merge pull request #18 from github/second-query
implement `ql/override-swapped-name`
2021-05-28 11:19:33 +02:00
Erik Krogh Kristensen
a5f5fed695 QL: Merge pull request #18 from github/second-query
implement `ql/override-swapped-name`
2021-05-28 11:19:33 +02:00
Erik Krogh Kristensen
2430dbfd04 update expected output 2021-05-28 09:16:54 +00:00
Erik Krogh Kristensen
e40d713878 QL: update expected output 2021-05-28 09:16:54 +00:00
shati-patel
d1c6660c32 add codeql to path 2021-05-28 10:16:16 +01:00
shati-patel
96a9c3446f QL: add codeql to path 2021-05-28 10:16:16 +01:00
Erik Krogh Kristensen
75d77b70cc implement ql/override-swapped-name 2021-05-28 09:14:57 +00:00
Erik Krogh Kristensen
50f5c83cf2 QL: implement ql/override-swapped-name 2021-05-28 09:14:57 +00:00
Erik Krogh Kristensen
19e33b2e29 bump precision 2021-05-28 09:14:57 +00:00
Erik Krogh Kristensen
d8b6579f59 QL: bump precision 2021-05-28 09:14:57 +00:00
shati-patel
ebcd27e1b3 Placeholder codeql workflow (wip) 2021-05-28 10:14:21 +01:00
shati-patel
da6a915779 QL: Placeholder codeql workflow (wip) 2021-05-28 10:14:21 +01:00
Tom Hvitved
c2c1a9200e Merge pull request #19 from github/more-variables
More variable resolution
2021-05-28 11:12:03 +02:00
Tom Hvitved
fac92ef2d0 QL: Merge pull request #19 from github/more-variables
More variable resolution
2021-05-28 11:12:03 +02:00
Tom Hvitved
dc5080c61d More variable resolution 2021-05-28 11:05:46 +02:00
Tom Hvitved
3e87a05de8 QL: More variable resolution 2021-05-28 11:05:46 +02:00
Tom Hvitved
e5a9bcd786 Merge pull request #15 from github/inheritance
Resolve inheritable members (fields and member predicates)
2021-05-28 11:05:28 +02:00
Tom Hvitved
36248cc803 QL: Merge pull request #15 from github/inheritance
Resolve inheritable members (fields and member predicates)
2021-05-28 11:05:28 +02:00
Joe Farebrother
0b1d109460 Resolution of inherited members 2021-05-28 11:00:01 +02:00
Joe Farebrother
d4d7c6de64 QL: Resolution of inherited members 2021-05-28 11:00:01 +02:00
Tom Hvitved
6d6c1f343d Merge pull request #16 from github/var-resolution
Variable resolution
2021-05-28 09:51:15 +02:00
Tom Hvitved
3a3f8096e7 QL: Merge pull request #16 from github/var-resolution
Variable resolution
2021-05-28 09:51:15 +02:00
Tom Hvitved
b20aa3fb07 Add variables to jump-to-def queries 2021-05-28 09:46:03 +02:00
Tom Hvitved
ef69a46f00 QL: Add variables to jump-to-def queries 2021-05-28 09:46:03 +02:00
Tom Hvitved
f99dc7b266 Variable resolution 2021-05-28 09:34:53 +02:00
Tom Hvitved
43ec1a77cf QL: Variable resolution 2021-05-28 09:34:53 +02:00
Erik Krogh Kristensen
28f2527f86 Merge pull request #17 from github/first-query
Add the `ql/primary-ql-class-consistency` query
2021-05-28 00:31:43 +02:00
Erik Krogh Kristensen
bf98e9636c QL: Merge pull request #17 from github/first-query
Add the `ql/primary-ql-class-consistency` query
2021-05-28 00:31:43 +02:00
Erik Krogh Kristensen
391c8150f5 make the test pass an auto-format check 2021-05-27 22:26:14 +00:00
Erik Krogh Kristensen
6f7cbf7194 QL: make the test pass an auto-format check 2021-05-27 22:26:14 +00:00
Erik Krogh Kristensen
d59f0df23f space 2021-05-27 22:21:14 +00:00
Erik Krogh Kristensen
09463f4e72 QL: space 2021-05-27 22:21:14 +00:00
Erik Krogh Kristensen
16cf439f6b run the query on our on code, and fix an error 2021-05-27 22:21:09 +00:00
Erik Krogh Kristensen
cb991fbf14 QL: run the query on our on code, and fix an error 2021-05-27 22:21:09 +00:00
Taus
9103e2697f Add getAChild
Joint work with: REDACTED
2021-05-27 22:17:10 +00:00
Taus
77758e5ba6 QL: Add getAChild
Joint work with: REDACTED
2021-05-27 22:17:10 +00:00
Erik Krogh Kristensen
497f0cd48b autoformat 2021-05-27 22:16:57 +00:00
Erik Krogh Kristensen
913cf53617 QL: autoformat 2021-05-27 22:16:57 +00:00
Erik Krogh Kristensen
79c99b0c61 update expected output after the introduction of a TopLevel ast node 2021-05-27 22:13:35 +00:00
Erik Krogh Kristensen
136b046b38 QL: update expected output after the introduction of a TopLevel ast node 2021-05-27 22:13:35 +00:00
Erik Krogh Kristensen
e8cc0ee453 Add the ql/primary-ql-class-consistency query 2021-05-27 22:08:18 +00:00
Erik Krogh Kristensen
d88cc79736 QL: Add the ql/primary-ql-class-consistency query 2021-05-27 22:08:18 +00:00
Tom Hvitved
967553d582 Merge pull request #14 from github/predicate-expr-resolution
Resolve predicate expressions
2021-05-27 20:39:39 +02:00
Tom Hvitved
4f410f53b8 QL: Merge pull request #14 from github/predicate-expr-resolution
Resolve predicate expressions
2021-05-27 20:39:39 +02:00
Tom Hvitved
8c59edefb2 Restrict resolvePredicateExpr to ClasslessPredicates 2021-05-27 20:28:46 +02:00
Tom Hvitved
0eabd4fcd9 QL: Restrict resolvePredicateExpr to ClasslessPredicates 2021-05-27 20:28:46 +02:00
Tom Hvitved
f713d8b13e Resolve predicate expressions 2021-05-27 20:26:19 +02:00
Tom Hvitved
2f74e3e765 QL: Resolve predicate expressions 2021-05-27 20:26:19 +02:00
Taus
e01fe66519 Add missing parents for ModuleExpr 2021-05-27 17:28:00 +00:00
Taus
93fa56fe79 QL: Add missing parents for ModuleExpr 2021-05-27 17:28:00 +00:00
Taus
c8cb81d1f9 missed a spot... 2021-05-27 17:20:01 +00:00
Taus
cdac3f9726 QL: missed a spot... 2021-05-27 17:20:01 +00:00
Taus
44c8e78873 super and aggregates containing expressions 2021-05-27 17:19:35 +00:00
Taus
dc11ec418b QL: super and aggregates containing expressions 2021-05-27 17:19:35 +00:00
shati-patel
1e9d8d0ca1 A bit more documentation 2021-05-27 18:07:49 +01:00
shati-patel
05e2ec3f82 QL: A bit more documentation 2021-05-27 18:07:49 +01:00
Taus
a4de52d135 Add unique as known aggregate name to treesitter 2021-05-27 16:48:59 +00:00
Taus
0e38056a3a QL: Add unique as known aggregate name to treesitter 2021-05-27 16:48:59 +00:00
Taus
2abb79cd57 Orphan fixes for aggregates 2021-05-27 16:48:38 +00:00
Taus
219b123271 QL: Orphan fixes for aggregates 2021-05-27 16:48:38 +00:00
shati-patel
fd3abe42bf Fix multiplication operator 2021-05-27 16:55:39 +01:00
shati-patel
625b9563bf QL: Fix multiplication operator 2021-05-27 16:55:39 +01:00
Taus
0337a0dc18 AST: range, in, set, and files 2021-05-27 15:47:46 +00:00
Taus
b9ea00c372 QL: AST: range, in, set, and files 2021-05-27 15:47:46 +00:00
shati-patel
59e85abe9e Merge branch 'main' of github.com:github/codeql-ql 2021-05-27 15:51:56 +01:00
shati-patel
e36915b0ef QL: Merge branch 'main' of github.com:github/codeql-ql 2021-05-27 15:51:56 +01:00
shati-patel
da65f75372 Add some more documentation 2021-05-27 15:51:40 +01:00
shati-patel
8ce59ff073 QL: Add some more documentation 2021-05-27 15:51:40 +01:00
Joe Farebrother
c66e7de6a8 Merge pull request #13 from github/type-expr-resolution
Type expression resolution
2021-05-27 15:48:20 +01:00
Joe Farebrother
0aa936d2d2 QL: Merge pull request #13 from github/type-expr-resolution
Type expression resolution
2021-05-27 15:48:20 +01:00
Joe Farebrother
45e6af2d14 Add jump-to-def support 2021-05-27 15:45:00 +01:00
Joe Farebrother
c6b5130ad5 QL: Add jump-to-def support 2021-05-27 15:45:00 +01:00
Taus
fe631a5eaf Add AST support for HOPs 2021-05-27 14:37:15 +00:00
Taus
f61471c451 QL: Add AST support for HOPs 2021-05-27 14:37:15 +00:00
Joe Farebrother
16005fa6cf Support aliases and unions 2021-05-27 15:25:37 +01:00
Joe Farebrother
cb3e971ebc QL: Support aliases and unions 2021-05-27 15:25:37 +01:00
Joe Farebrother
719ef68aeb `Merge branch 'main' into type-expr-resolution 2021-05-27 15:12:49 +01:00
Joe Farebrother
3a8e1779d9 QL: `Merge branch 'main' into type-expr-resolution 2021-05-27 15:12:49 +01:00
Taus
2882f6d37c Link up ModuleExpr with PredicateCall 2021-05-27 14:11:20 +00:00
Taus
69b4d577d5 QL: Link up ModuleExpr with PredicateCall 2021-05-27 14:11:20 +00:00
Joe Farebrother
9580362332 Fixes for resolution and consistency query 2021-05-27 15:05:42 +01:00
Joe Farebrother
5ec1068230 QL: Fixes for resolution and consistency query 2021-05-27 15:05:42 +01:00
Taus
e09a012064 Support class unions 2021-05-27 14:01:21 +00:00
Taus
a1fc6391d7 QL: Support class unions 2021-05-27 14:01:21 +00:00
Joe Farebrother
fc2f9b5ab6 Add type expression resolution 2021-05-27 14:48:26 +01:00
Joe Farebrother
d5bf0cb33f QL: Add type expression resolution 2021-05-27 14:48:26 +01:00
Taus
97468a3935 Support predicate foo = bar/5; 2021-05-27 13:18:31 +00:00
Taus
158b50f482 QL: Support predicate foo = bar/5; 2021-05-27 13:18:31 +00:00
Taus
359b7d6b39 Add support for class Foo = Bar; 2021-05-27 13:08:30 +00:00
Taus
192ac4cae3 QL: Add support for class Foo = Bar; 2021-05-27 13:08:30 +00:00
Taus
59c4e170a8 Make all calls formulas 2021-05-27 12:57:39 +00:00
Taus
bb50f90a64 QL: Make all calls formulas 2021-05-27 12:57:39 +00:00
Taus
20e72d3304 Add AST node for expression annotations 2021-05-27 12:52:37 +00:00
Taus
59c0c06a8e QL: Add AST node for expression annotations 2021-05-27 12:52:37 +00:00
Taus
6aa64ba2cc Fix up NoneCall
In some contexts, `none()` is a formula. This means in general we cannot
assume `Call` is an `Expr`, but only know that it's an `AstNode`.
2021-05-27 12:41:22 +00:00
Taus
b79e295c71 QL: Fix up NoneCall
In some contexts, `none()` is a formula. This means in general we cannot
assume `Call` is an `Expr`, but only know that it's an `AstNode`.
2021-05-27 12:41:22 +00:00
Taus
a99a6a4721 Add use of parentheses to printAst test 2021-05-27 12:25:29 +00:00
Taus
3211545a63 QL: Add use of parentheses to printAst test 2021-05-27 12:25:29 +00:00
Taus
21e8993c71 Hide parentheses in AST
Joint work with erik-krogh
2021-05-27 12:17:40 +00:00
Taus
b4f67c9d5f QL: Hide parentheses in AST
Joint work with erik-krogh
2021-05-27 12:17:40 +00:00
Tom Hvitved
80761ba069 Make jump-to-def queries work for module references 2021-05-27 12:58:52 +02:00
Tom Hvitved
aa23ec0714 QL: Make jump-to-def queries work for module references 2021-05-27 12:58:52 +02:00
shati-patel
65bdb1722c More QLDoc 2021-05-27 11:52:48 +01:00
shati-patel
b4a03fe3f0 QL: More QLDoc 2021-05-27 11:52:48 +01:00
Tom Hvitved
871f4b1be8 Merge pull request #8 from github/module-resolution
Module resolution
2021-05-27 12:45:07 +02:00
Tom Hvitved
e1501dc830 QL: Merge pull request #8 from github/module-resolution
Module resolution
2021-05-27 12:45:07 +02:00
Tom Hvitved
ebb1cd3f8f Module resolution 2021-05-27 12:42:46 +02:00
Tom Hvitved
f3cae6bb25 QL: Module resolution 2021-05-27 12:42:46 +02:00
Taus
0aa7127e47 link up NewType correctly 2021-05-27 10:41:43 +00:00
Taus
b3844cb715 QL: link up NewType correctly 2021-05-27 10:41:43 +00:00
Taus
c89e924b67 regenerate TreeSitter.ql 2021-05-27 10:24:00 +00:00
Taus
5a3da4b9eb QL: regenerate TreeSitter.ql 2021-05-27 10:24:00 +00:00
Erik Krogh Kristensen
c449e45b72 Merge pull request #11 from github/greenbar
Trying to get a green bar
2021-05-27 12:16:43 +02:00
Erik Krogh Kristensen
ae164a6049 QL: Merge pull request #11 from github/greenbar
Trying to get a green bar
2021-05-27 12:16:43 +02:00
Erik Krogh Kristensen
1d7f43206e update the printAst test 2021-05-27 10:13:42 +00:00
Erik Krogh Kristensen
ef83783d11 QL: update the printAst test 2021-05-27 10:13:42 +00:00
Erik Krogh Kristensen
4921b6cf56 switch to having the pretty AST by default in printAst 2021-05-27 10:13:33 +00:00
Erik Krogh Kristensen
58fb239cf0 QL: switch to having the pretty AST by default in printAst 2021-05-27 10:13:33 +00:00
Taus
cdd9978c30 ifs, implications, instanceof 2021-05-27 10:12:41 +00:00
Taus
3ac7fa8369 QL: ifs, implications, instanceof 2021-05-27 10:12:41 +00:00
Erik Krogh Kristensen
be495b28da add cases to the getParent relation 2021-05-27 10:12:03 +00:00
Erik Krogh Kristensen
3aebdcce7b QL: add cases to the getParent relation 2021-05-27 10:12:03 +00:00
Erik Krogh Kristensen
79789e28a1 calls and inline casts 2021-05-27 10:04:20 +00:00
Erik Krogh Kristensen
a38d9a3cbf QL: calls and inline casts 2021-05-27 10:04:20 +00:00
shati-patel
d9a7f10cfe Add more QLDoc 2021-05-27 10:56:40 +01:00
shati-patel
83a38eebab QL: Add more QLDoc 2021-05-27 10:56:40 +01:00
Shati Patel
14ee979bbe Merge pull request #10 from github/more-expressions
Add more expressions
2021-05-27 10:44:49 +01:00
Shati Patel
1aecd5738b QL: Merge pull request #10 from github/more-expressions
Add more expressions
2021-05-27 10:44:49 +01:00
shati-patel
8f031cda5f Add more expressions 2021-05-27 10:41:29 +01:00
shati-patel
fb30a1c893 QL: Add more expressions 2021-05-27 10:41:29 +01:00
Erik Krogh Kristensen
c4c0a63104 use moduleExpr in Type 2021-05-27 09:31:47 +00:00
Erik Krogh Kristensen
01ae97bf22 QL: use moduleExpr in Type 2021-05-27 09:31:47 +00:00
Tom Hvitved
01d4b8a41c Add module expressions and module aliases 2021-05-27 11:28:37 +02:00
Tom Hvitved
7b64df51ab QL: Add module expressions and module aliases 2021-05-27 11:28:37 +02:00
Tom Hvitved
509e789510 Merge pull request #9 from github/dataset-measure
Update dataset_measure.yml
2021-05-27 10:48:09 +02:00
Tom Hvitved
9f68fdfb61 QL: Merge pull request #9 from github/dataset-measure
Update dataset_measure.yml
2021-05-27 10:48:09 +02:00
Tom Hvitved
aaa7973906 Update dataset_measure.yml 2021-05-27 10:39:51 +02:00
Tom Hvitved
ff591a0c57 QL: Update dataset_measure.yml 2021-05-27 10:39:51 +02:00
Erik Krogh Kristensen
48c9e5f3b8 Merge pull request #7 from github/ast
AST layer
2021-05-27 10:39:04 +02:00
Erik Krogh Kristensen
d941e7cdb8 QL: Merge pull request #7 from github/ast
AST layer
2021-05-27 10:39:04 +02:00
Tom Hvitved
09d0cdbaf8 Add ModuleMember::isPrivate() 2021-05-27 10:27:57 +02:00
Tom Hvitved
197a36daf6 QL: Add ModuleMember::isPrivate() 2021-05-27 10:27:57 +02:00
Erik Krogh Kristensen
ab20f8f74e add support for aggregates 2021-05-27 08:23:15 +00:00
Erik Krogh Kristensen
b83c19f27b QL: add support for aggregates 2021-05-27 08:23:15 +00:00
Erik Krogh Kristensen
fec3d745ca make sure Literal is an Expr 2021-05-27 07:31:44 +00:00
Erik Krogh Kristensen
abec79cb0f QL: make sure Literal is an Expr 2021-05-27 07:31:44 +00:00
Erik Krogh Kristensen
ee9e1914b0 literals and fixes 2021-05-26 21:35:01 +00:00
Erik Krogh Kristensen
6f5499eefe QL: literals and fixes 2021-05-26 21:35:01 +00:00
Erik Krogh Kristensen
a692794178 add types 2021-05-26 21:35:01 +00:00
Erik Krogh Kristensen
c075f370c7 QL: add types 2021-05-26 21:35:01 +00:00
Taus
ec98e8a82d Add convenience methods for aggregates 2021-05-26 21:25:42 +00:00
Taus
9536e591fb QL: Add convenience methods for aggregates 2021-05-26 21:25:42 +00:00
Taus
4eb836ca9b AST for quantifiers, negation 2021-05-26 21:06:04 +00:00
Taus
d4782e67fe QL: AST for quantifiers, negation 2021-05-26 21:06:04 +00:00
Erik Krogh Kristensen
3057790071 ast for imports, modules, and various fixes 2021-05-26 19:39:54 +00:00
Erik Krogh Kristensen
ad7d35df2a QL: ast for imports, modules, and various fixes 2021-05-26 19:39:54 +00:00
Taus
2addbfabd0 More work on ComparisonFormula 2021-05-26 18:12:06 +00:00
Taus
0ddac5bcee QL: More work on ComparisonFormula 2021-05-26 18:12:06 +00:00
Taus
eafbd15da0 Merge branch 'main' into ast 2021-05-26 17:38:44 +00:00
Taus
cd15cec629 QL: Merge branch 'main' into ast 2021-05-26 17:38:44 +00:00
Taus
2443ad3314 Add body as a field of charpred 2021-05-26 17:26:15 +00:00
Taus
e554fa8277 QL: Add body as a field of charpred 2021-05-26 17:26:15 +00:00
Taus
94c1321e43 WIP formulas and expressions
Joint work with shati-patel.
2021-05-26 16:21:01 +00:00
Taus
29c32a924f QL: WIP formulas and expressions
Joint work with shati-patel.
2021-05-26 16:21:01 +00:00
Erik Krogh Kristensen
28968163e0 Merge remote-tracking branch 'origin/main' into ast 2021-05-26 15:02:23 +00:00
Erik Krogh Kristensen
20f495dfbf QL: Merge remote-tracking branch 'origin/main' into ast 2021-05-26 15:02:23 +00:00
Erik Krogh Kristensen
7a4a4e9cdd implement more AST cases 2021-05-26 15:01:55 +00:00
Erik Krogh Kristensen
a453c32e71 QL: implement more AST cases 2021-05-26 15:01:55 +00:00
Taus
9b8acdb37f Don't printAst ReservedWords 2021-05-26 14:28:33 +00:00
Taus
88972f04f4 QL: Don't printAst ReservedWords 2021-05-26 14:28:33 +00:00
Erik Krogh Kristensen
8fa3a425a5 slightly more AST stuff 2021-05-26 14:18:25 +00:00
Erik Krogh Kristensen
9a9b6f71c2 QL: slightly more AST stuff 2021-05-26 14:18:25 +00:00
Erik Krogh Kristensen
cb49c1ec24 switch printAst query to use new pretty AST layer 2021-05-26 14:04:23 +00:00
Erik Krogh Kristensen
407a3b5d3d QL: switch printAst query to use new pretty AST layer 2021-05-26 14:04:23 +00:00
Erik Krogh Kristensen
a4603a49a1 fix format (again) 2021-05-26 13:53:15 +00:00
Erik Krogh Kristensen
7f2c999b8e QL: fix format (again) 2021-05-26 13:53:15 +00:00
Erik Krogh Kristensen
00b33acfe9 fix format 2021-05-26 13:50:19 +00:00
Erik Krogh Kristensen
e820a5a1e2 QL: fix format 2021-05-26 13:50:19 +00:00
Erik Krogh Kristensen
344c19f049 extremely minimal AST layer 2021-05-26 13:48:02 +00:00
Erik Krogh Kristensen
e35ab675ba QL: extremely minimal AST layer 2021-05-26 13:48:02 +00:00
Taus
f2edd7724c Record annotation names in the AST 2021-05-26 13:14:52 +00:00
Taus
c91a2b88fd QL: Record annotation names in the AST 2021-05-26 13:14:52 +00:00
Erik Krogh Kristensen
e469ce171d don't print LineComment (they were disconnected from the root), and a bit of printAst performance 2021-05-26 13:12:44 +00:00
Erik Krogh Kristensen
955f4d4d24 QL: don't print LineComment (they were disconnected from the root), and a bit of printAst performance 2021-05-26 13:12:44 +00:00
shati-patel
80b508aa03 de-ruby some more things 2021-05-26 14:09:09 +01:00
shati-patel
bae0c260d9 QL: de-ruby some more things 2021-05-26 14:09:09 +01:00
Erik Krogh Kristensen
44311e2ace Merge pull request #5 from github/qltest-testing
Get qlTest to work
2021-05-26 14:48:20 +02:00
Erik Krogh Kristensen
54e449f3c6 QL: Merge pull request #5 from github/qltest-testing
Get qlTest to work
2021-05-26 14:48:20 +02:00
Erik Krogh Kristensen
f916aa9a37 better printAst test 2021-05-26 12:44:50 +00:00
Erik Krogh Kristensen
9772f35984 QL: better printAst test 2021-05-26 12:44:50 +00:00
Erik Krogh Kristensen
a015b9499a add test for the printAst query 2021-05-26 12:38:21 +00:00
Erik Krogh Kristensen
5494db9b33 QL: add test for the printAst query 2021-05-26 12:38:21 +00:00
Erik Krogh Kristensen
4ca756ddf9 insert placeholder (that compiles) in localDefinitions.ql 2021-05-26 12:29:12 +00:00
Erik Krogh Kristensen
571b949a06 QL: insert placeholder (that compiles) in localDefinitions.ql 2021-05-26 12:29:12 +00:00
Erik Krogh Kristensen
3addd03c29 insert placeholder (that compiles) in localReferences.ql 2021-05-26 12:29:12 +00:00
Erik Krogh Kristensen
fe6595ec02 QL: insert placeholder (that compiles) in localReferences.ql 2021-05-26 12:29:12 +00:00
Taus
f351100f86 Merge pull request #6 from github/support-expr-annotations
Support expression annotations
2021-05-26 14:25:25 +02:00
Taus
36497ad50a QL: Merge pull request #6 from github/support-expr-annotations
Support expression annotations
2021-05-26 14:25:25 +02:00
Taus
0f6d6df745 Support expression annotations 2021-05-26 12:21:19 +00:00
Taus
6f8f0bb749 QL: Support expression annotations 2021-05-26 12:21:19 +00:00
Tom Hvitved
0c3ce12520 Update ql.qll 2021-05-26 14:00:36 +02:00
Tom Hvitved
8493f515ee QL: Update ql.qll 2021-05-26 14:00:36 +02:00
Erik Krogh Kristensen
9e5a4b9fbb get printAst to work 2021-05-26 11:58:14 +00:00
Erik Krogh Kristensen
530df51e8f QL: get printAst to work 2021-05-26 11:58:14 +00:00
shati-patel
041c07463f another bit of cleanup 2021-05-26 12:38:40 +01:00
shati-patel
1b8f702ec6 QL: another bit of cleanup 2021-05-26 12:38:40 +01:00
Tom Hvitved
419e69b2b5 More cleanup 2021-05-26 13:25:43 +02:00
Tom Hvitved
68e9f9657b QL: More cleanup 2021-05-26 13:25:43 +02:00
shati-patel
5b830fdcd1 Fix commands on Windows (take 2) 2021-05-26 12:24:54 +01:00
shati-patel
f9f8dfb619 QL: Fix commands on Windows (take 2) 2021-05-26 12:24:54 +01:00
Erik Krogh Kristensen
f04005e4ca update dbscheme to fix capitalization 2021-05-26 11:23:22 +00:00
Erik Krogh Kristensen
2df49aaae8 QL: update dbscheme to fix capitalization 2021-05-26 11:23:22 +00:00
Erik Krogh Kristensen
ecde34fdf4 Merge pull request #4 from github/fixCap
fix snake_casing of generated ql identifiers
2021-05-26 13:18:30 +02:00
Erik Krogh Kristensen
786f756591 QL: Merge pull request #4 from github/fixCap
fix snake_casing of generated ql identifiers
2021-05-26 13:18:30 +02:00
shati-patel
d7e53bfdb3 Fix Windows commands 2021-05-26 12:12:36 +01:00
shati-patel
407f63b7d2 QL: Fix Windows commands 2021-05-26 12:12:36 +01:00
Erik Krogh Kristensen
02e1d424b2 fix snake_casing of generated ql identifiers 2021-05-26 11:12:05 +00:00
Erik Krogh Kristensen
b0d86d466f QL: fix snake_casing of generated ql identifiers 2021-05-26 11:12:05 +00:00
Shati Patel
021c0a03b4 Update devcontainer files 2021-05-26 10:22:53 +00:00
Shati Patel
6bb91f4080 QL: Update devcontainer files 2021-05-26 10:22:53 +00:00
Tom Hvitved
815bd4fb92 Update workflow files 2021-05-26 11:50:37 +02:00
Tom Hvitved
cacefbe075 QL: Update workflow files 2021-05-26 11:50:37 +02:00
Tom Hvitved
ec15ba8e9c Update Readme 2021-05-26 11:46:34 +02:00
Tom Hvitved
f5c1b2e645 QL: Update Readme 2021-05-26 11:46:34 +02:00
Tom Hvitved
6d04ef46f4 Change more Ruby to QL 2021-05-26 11:43:18 +02:00
Tom Hvitved
823ab1076a QL: Change more Ruby to QL 2021-05-26 11:43:18 +02:00
Tom Hvitved
7bac6a07b6 Initial commit 2021-05-26 11:32:30 +02:00
704 changed files with 68979 additions and 6188 deletions

View File

@@ -10,7 +10,16 @@
"javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml",
"misc/legacy-support/*/qlpack.yml",
"misc/suite-helpers/qlpack.yml",
"ruby/extractor-pack/codeql-extractor.yml",
"ruby/ql/consistency-queries/qlpack.yml",
"ruby/extractor-pack/codeql-extractor.yml"
]
}
"ql/ql/consistency-queries/qlpack.yml",
"ql/extractor-pack/codeql-extractor.yml"
],
"versionPolicies": {
"default": {
"requireChangeNotes": true,
"committedPrereleaseSuffix": "dev",
"committedVersion": "nextPatchRelease"
}
}
}

152
.github/workflows/ql-for-ql-build.yml vendored Normal file
View File

@@ -0,0 +1,152 @@
name: Run QL for QL
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
CARGO_TERM_COLOR: always
jobs:
queries:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Find codeql
id: find-codeql
uses: github/codeql-action/init@esbena/ql
with:
languages: javascript # does not matter
- name: Get CodeQL version
id: get-codeql-version
run: |
echo "::set-output name=version::$("${CODEQL}" --version | head -n 1 | rev | cut -d " " -f 1 | rev)"
shell: bash
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Cache queries
id: cache-queries
uses: actions/cache@v2
with:
path: ${{ runner.temp }}/query-pack.zip
key: queries-${{ hashFiles('ql/**/*.ql*') }}-${{ hashFiles('ql/ql/src/ql.dbscheme*') }}-${{ steps.get-codeql-version.outputs.version }}
- name: Build query pack
if: steps.cache-queries.outputs.cache-hit != 'true'
run: |
cd ql/ql/src
"${CODEQL}" pack create
cd .codeql/pack/codeql/ql-all/0.0.0
zip "${PACKZIP}" -r .
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
PACKZIP: ${{ runner.temp }}/query-pack.zip
- name: Upload query pack
uses: actions/upload-artifact@v2
with:
name: query-pack-zip
path: ${{ runner.temp }}/query-pack.zip
extractors:
strategy:
fail-fast: false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/cache@v2
with:
path: |
~/.cargo/registry
~/.cargo/git
ql/target
key: ${{ runner.os }}-rust-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Check formatting
run: cd ql; cargo fmt --all -- --check
- name: Build
run: cd ql; cargo build --verbose
- name: Run tests
run: cd ql; cargo test --verbose
- name: Release build
run: cd ql; cargo build --release
- name: Generate dbscheme
run: ql/target/release/ql-generator --dbscheme ql/ql/src/ql.dbscheme --library ql/ql/src/codeql_ql/ast/internal/TreeSitter.qll
- uses: actions/upload-artifact@v2
with:
name: extractor-ubuntu-latest
path: |
ql/target/release/ql-extractor
ql/target/release/ql-extractor.exe
retention-days: 1
package:
runs-on: ubuntu-latest
needs:
- extractors
- queries
steps:
- uses: actions/checkout@v2
- uses: actions/download-artifact@v2
with:
name: query-pack-zip
path: query-pack-zip
- uses: actions/download-artifact@v2
with:
name: extractor-ubuntu-latest
path: linux64
- run: |
unzip query-pack-zip/*.zip -d pack
cp -r ql/codeql-extractor.yml ql/tools ql/ql/src/ql.dbscheme.stats pack/
mkdir -p pack/tools/linux64
if [[ -f linux64/ql-extractor ]]; then
cp linux64/ql-extractor pack/tools/linux64/extractor
chmod +x pack/tools/linux64/extractor
fi
cd pack
zip -rq ../codeql-ql.zip .
- uses: actions/upload-artifact@v2
with:
name: codeql-ql-pack
path: codeql-ql.zip
retention-days: 1
analyze:
runs-on: ubuntu-latest
needs:
- package
steps:
- name: Download pack
uses: actions/download-artifact@v2
with:
name: codeql-ql-pack
path: ${{ runner.temp }}/codeql-ql-pack-artifact
- name: Prepare pack
run: |
unzip "${PACK_ARTIFACT}/*.zip" -d "${PACK}"
env:
PACK_ARTIFACT: ${{ runner.temp }}/codeql-ql-pack-artifact
PACK: ${{ runner.temp }}/pack
- name: Hack codeql-action options
run: |
JSON=$(jq -nc --arg pack "${PACK}" '.resolve.queries=["--search-path", $pack] | .resolve.extractor=["--search-path", $pack] | .database.init=["--search-path", $pack]')
echo "CODEQL_ACTION_EXTRA_OPTIONS=${JSON}" >> ${GITHUB_ENV}
env:
PACK: ${{ runner.temp }}/pack
- name: Checkout repository
uses: actions/checkout@v2
- name: Initialize CodeQL
uses: github/codeql-action/init@esbena/ql
with:
languages: ql
db-location: ${{ runner.temp }}/db
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@esbena/ql

View File

@@ -0,0 +1,84 @@
name: Collect database stats for QL for QL
on:
push:
branches: [main]
paths:
- ql/ql/src/ql.dbscheme
pull_request:
branches: [main]
paths:
- ql/ql/src/ql.dbscheme
workflow_dispatch:
jobs:
measure:
env:
CODEQL_THREADS: 4 # TODO: remove this once it's set by the CLI
strategy:
matrix:
repo:
- github/codeql
- github/codeql-go
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Find codeql
id: find-codeql
uses: github/codeql-action/init@esbena/ql
with:
languages: javascript # does not matter
- uses: actions/cache@v2
with:
path: |
~/.cargo/registry
~/.cargo/git
ql/target
key: ${{ runner.os }}-qltest-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Build Extractor
run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./create-extractor-pack.sh
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Checkout ${{ matrix.repo }}
uses: actions/checkout@v2
with:
repository: ${{ matrix.repo }}
path: ${{ github.workspace }}/repo
- name: Create database
run: |
"${CODEQL}" database create \
--search-path "ql/extractor-pack" \
--threads 4 \
--language ql --source-root "${{ github.workspace }}/repo" \
"${{ runner.temp }}/database"
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Measure database
run: |
mkdir -p "stats/${{ matrix.repo }}"
"${CODEQL}" dataset measure --threads 4 --output "stats/${{ matrix.repo }}/stats.xml" "${{ runner.temp }}/database/db-ql"
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- uses: actions/upload-artifact@v2
with:
name: measurements
path: stats
retention-days: 1
merge:
runs-on: ubuntu-latest
needs: measure
steps:
- uses: actions/checkout@v2
- uses: actions/download-artifact@v2
with:
name: measurements
path: stats
- run: |
python -m pip install --user lxml
find stats -name 'stats.xml' -print0 | sort -z | xargs -0 python ql/scripts/merge_stats.py --output ql/ql/src/ql.dbscheme.stats --normalise ql_tokeninfo
- uses: actions/upload-artifact@v2
with:
name: ql.dbscheme.stats
path: ql/ql/src/ql.dbscheme.stats

52
.github/workflows/ql-for-ql-tests.yml vendored Normal file
View File

@@ -0,0 +1,52 @@
name: Run QL for QL Tests
on:
push:
branches: [main]
paths:
- ql/*
pull_request:
branches: [main]
paths:
- ql/*
env:
CARGO_TERM_COLOR: always
jobs:
qltest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Find codeql
id: find-codeql
uses: github/codeql-action/init@esbena/ql
with:
languages: javascript # does not matter
- uses: actions/cache@v2
with:
path: |
~/.cargo/registry
~/.cargo/git
ql/target
key: ${{ runner.os }}-qltest-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Build extractor
run: |
cd ql;
codeqlpath=$(dirname ${{ steps.find-codeql.outputs.codeql-path }});
env "PATH=$PATH:$codeqlpath" ./create-extractor-pack.sh
- name: Run QL tests
run: |
"${CODEQL}" test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}/ql/extractor-pack" --consistency-queries ql/ql/consistency-queries ql/ql/test
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Check QL formatting
run: |
find ql/ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 "${CODEQL}" query format --check-only
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Check QL compilation
run: |
"${CODEQL}" query compile --check-only --threads=4 --warnings=error --search-path "${{ github.workspace }}/ql/extractor-pack" "ql/ql/src" "ql/ql/examples"
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}

View File

@@ -25,3 +25,6 @@
/docs/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers
/docs/ql-language-reference/ @github/codeql-frontend-reviewers
/docs/query-*-style-guide.md @github/codeql-analysis-reviewers
# QL for QL reviewers
/ql/ @erik-krogh @tausbn

View File

@@ -17,7 +17,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="16.9.0" />
<PackageReference Include="Microsoft.Build" Version="16.11.0" />
</ItemGroup>
<ItemGroup>

7
cpp/ql/lib/CHANGELOG.md Normal file
View File

@@ -0,0 +1,7 @@
## 0.0.4
### New Features
* The QL library `semmle.code.cpp.commons.Exclusions` now contains a predicate
`isFromSystemMacroDefinition` for identifying code that originates from a
macro outside the project being analyzed.

View File

@@ -0,0 +1,7 @@
## 0.0.4
### New Features
* The QL library `semmle.code.cpp.commons.Exclusions` now contains a predicate
`isFromSystemMacroDefinition` for identifying code that originates from a
macro outside the project being analyzed.

View File

@@ -0,0 +1,2 @@
---
lastReleaseVersion: 0.0.4

View File

@@ -1,7 +1,8 @@
name: codeql/cpp-all
version: 0.0.2
version: 0.0.5-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp
library: true
dependencies:
codeql/cpp-upgrades: 0.0.2
codeql/cpp-upgrades: ^0.0.3

View File

@@ -9,6 +9,83 @@ import semmle.code.cpp.models.interfaces.FormattingFunction
private import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
private newtype TBufferWriteEstimationReason =
TNoSpecifiedEstimateReason() or
TTypeBoundsAnalysis() or
TValueFlowAnalysis()
/**
* A reason for a specific buffer write size estimate.
*/
abstract class BufferWriteEstimationReason extends TBufferWriteEstimationReason {
/**
* Returns the name of the concrete class.
*/
abstract string toString();
/**
* Returns a human readable representation of this reason.
*/
abstract string getDescription();
/**
* Combine estimate reasons. Used to give a reason for the size of a format string
* conversion given reasons coming from its individual specifiers.
*/
abstract BufferWriteEstimationReason combineWith(BufferWriteEstimationReason other);
}
/**
* No particular reason given. This is currently used for backward compatibility so that
* classes derived from BufferWrite and overriding `getMaxData/0` still work with the
* queries as intended.
*/
class NoSpecifiedEstimateReason extends BufferWriteEstimationReason, TNoSpecifiedEstimateReason {
override string toString() { result = "NoSpecifiedEstimateReason" }
override string getDescription() { result = "no reason specified" }
override BufferWriteEstimationReason combineWith(BufferWriteEstimationReason other) {
// this reason should not be used in format specifiers, so it should not be combined
// with other reasons
none()
}
}
/**
* The estimation comes from rough bounds just based on the type (e.g.
* `0 <= x < 2^32` for an unsigned 32 bit integer).
*/
class TypeBoundsAnalysis extends BufferWriteEstimationReason, TTypeBoundsAnalysis {
override string toString() { result = "TypeBoundsAnalysis" }
override string getDescription() { result = "based on type bounds" }
override BufferWriteEstimationReason combineWith(BufferWriteEstimationReason other) {
other != TNoSpecifiedEstimateReason() and result = TTypeBoundsAnalysis()
}
}
/**
* The estimation comes from non trivial bounds found via actual flow analysis.
* For example
* ```
* unsigned u = x;
* if (u < 1000) {
* //... <- estimation done here based on u
* }
* ```
*/
class ValueFlowAnalysis extends BufferWriteEstimationReason, TValueFlowAnalysis {
override string toString() { result = "ValueFlowAnalysis" }
override string getDescription() { result = "based on flow analysis of value bounds" }
override BufferWriteEstimationReason combineWith(BufferWriteEstimationReason other) {
other != TNoSpecifiedEstimateReason() and result = other
}
}
class PrintfFormatAttribute extends FormatAttribute {
PrintfFormatAttribute() { this.getArchetype() = ["printf", "__printf__"] }
}
@@ -990,7 +1067,14 @@ class FormatLiteral extends Literal {
* conversion specifier of this format string; has no result if this cannot
* be determined.
*/
int getMaxConvertedLength(int n) {
int getMaxConvertedLength(int n) { result = max(getMaxConvertedLength(n, _)) }
/**
* Gets the maximum length of the string that can be produced by the nth
* conversion specifier of this format string, specifying the estimation reason;
* has no result if this cannot be determined.
*/
int getMaxConvertedLength(int n, BufferWriteEstimationReason reason) {
exists(int len |
(
(
@@ -1002,10 +1086,12 @@ class FormatLiteral extends Literal {
) and
(
this.getConversionChar(n) = "%" and
len = 1
len = 1 and
reason = TValueFlowAnalysis()
or
this.getConversionChar(n).toLowerCase() = "c" and
len = 1 // e.g. 'a'
len = 1 and
reason = TValueFlowAnalysis() // e.g. 'a'
or
this.getConversionChar(n).toLowerCase() = "f" and
exists(int dot, int afterdot |
@@ -1019,7 +1105,8 @@ class FormatLiteral extends Literal {
afterdot = 6
) and
len = 1 + 309 + dot + afterdot
) // e.g. -1e308="-100000"...
) and
reason = TTypeBoundsAnalysis() // e.g. -1e308="-100000"...
or
this.getConversionChar(n).toLowerCase() = "e" and
exists(int dot, int afterdot |
@@ -1033,7 +1120,8 @@ class FormatLiteral extends Literal {
afterdot = 6
) and
len = 1 + 1 + dot + afterdot + 1 + 1 + 3
) // -1e308="-1.000000e+308"
) and
reason = TTypeBoundsAnalysis() // -1e308="-1.000000e+308"
or
this.getConversionChar(n).toLowerCase() = "g" and
exists(int dot, int afterdot |
@@ -1056,67 +1144,80 @@ class FormatLiteral extends Literal {
// (e.g. 123456, 0.000123456 are just OK)
// so case %f can be at most P characters + 4 zeroes, sign, dot = P + 6
len = (afterdot.maximum(1) + 6).maximum(1 + 1 + dot + afterdot + 1 + 1 + 3)
) // (e.g. "-1.59203e-319")
) and
reason = TTypeBoundsAnalysis() // (e.g. "-1.59203e-319")
or
this.getConversionChar(n).toLowerCase() = ["d", "i"] and
// e.g. -2^31 = "-2147483648"
len =
min(float cand |
// The first case handles length sub-specifiers
// Subtract one in the exponent because one bit is for the sign.
// Add 1 to account for the possible sign in the output.
cand = 1 + lengthInBase10(2.pow(this.getIntegralDisplayType(n).getSize() * 8 - 1))
or
// The second case uses range analysis to deduce a length that's shorter than the length
// of the number -2^31.
exists(Expr arg, float lower, float upper |
arg = this.getUse().getConversionArgument(n) and
lower = lowerBound(arg.getFullyConverted()) and
upper = upperBound(arg.getFullyConverted())
|
cand =
max(int cand0 |
// Include the sign bit in the length if it can be negative
(
if lower < 0
then cand0 = 1 + lengthInBase10(lower.abs())
else cand0 = lengthInBase10(lower)
)
or
(
if upper < 0
then cand0 = 1 + lengthInBase10(upper.abs())
else cand0 = lengthInBase10(upper)
)
exists(float typeBasedBound, float valueBasedBound |
// The first case handles length sub-specifiers
// Subtract one in the exponent because one bit is for the sign.
// Add 1 to account for the possible sign in the output.
typeBasedBound =
1 + lengthInBase10(2.pow(this.getIntegralDisplayType(n).getSize() * 8 - 1)) and
// The second case uses range analysis to deduce a length that's shorter than the length
// of the number -2^31.
exists(Expr arg, float lower, float upper, float typeLower, float typeUpper |
arg = this.getUse().getConversionArgument(n) and
lower = lowerBound(arg.getFullyConverted()) and
upper = upperBound(arg.getFullyConverted()) and
typeLower = exprMinVal(arg.getFullyConverted()) and
typeUpper = exprMaxVal(arg.getFullyConverted())
|
valueBasedBound =
max(int cand |
// Include the sign bit in the length if it can be negative
(
if lower < 0
then cand = 1 + lengthInBase10(lower.abs())
else cand = lengthInBase10(lower)
)
or
(
if upper < 0
then cand = 1 + lengthInBase10(upper.abs())
else cand = lengthInBase10(upper)
)
) and
(
if lower > typeLower or upper < typeUpper
then reason = TValueFlowAnalysis()
else reason = TTypeBoundsAnalysis()
)
)
) and
len = valueBasedBound.minimum(typeBasedBound)
)
or
this.getConversionChar(n).toLowerCase() = "u" and
// e.g. 2^32 - 1 = "4294967295"
len =
min(float cand |
// The first case handles length sub-specifiers
cand = 2.pow(this.getIntegralDisplayType(n).getSize() * 8)
or
// The second case uses range analysis to deduce a length that's shorter than
// the length of the number 2^31 - 1.
exists(Expr arg, float lower |
arg = this.getUse().getConversionArgument(n) and
lower = lowerBound(arg.getFullyConverted())
|
cand =
max(float cand0 |
exists(float typeBasedBound, float valueBasedBound |
// The first case handles length sub-specifiers
typeBasedBound = lengthInBase10(2.pow(this.getIntegralDisplayType(n).getSize() * 8) - 1) and
// The second case uses range analysis to deduce a length that's shorter than
// the length of the number 2^31 - 1.
exists(Expr arg, float lower, float upper, float typeLower, float typeUpper |
arg = this.getUse().getConversionArgument(n) and
lower = lowerBound(arg.getFullyConverted()) and
upper = upperBound(arg.getFullyConverted()) and
typeLower = exprMinVal(arg.getFullyConverted()) and
typeUpper = exprMaxVal(arg.getFullyConverted())
|
valueBasedBound =
lengthInBase10(max(float cand |
// If lower can be negative we use `(unsigned)-1` as the candidate value.
lower < 0 and
cand0 = 2.pow(any(IntType t | t.isUnsigned()).getSize() * 8)
cand = 2.pow(any(IntType t | t.isUnsigned()).getSize() * 8)
or
cand0 = upperBound(arg.getFullyConverted())
)
cand = upper
)) and
(
if lower > typeLower or upper < typeUpper
then reason = TValueFlowAnalysis()
else reason = TTypeBoundsAnalysis()
)
|
lengthInBase10(cand)
)
) and
len = valueBasedBound.minimum(typeBasedBound)
)
or
this.getConversionChar(n).toLowerCase() = "x" and
// e.g. "12345678"
@@ -1135,7 +1236,8 @@ class FormatLiteral extends Literal {
(
if this.hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
)
)
) and
reason = TTypeBoundsAnalysis()
or
this.getConversionChar(n).toLowerCase() = "p" and
exists(PointerType ptrType, int baseLen |
@@ -1144,7 +1246,8 @@ class FormatLiteral extends Literal {
(
if this.hasAlternateFlag(n) then len = 2 + baseLen else len = baseLen // "0x"
)
)
) and
reason = TValueFlowAnalysis()
or
this.getConversionChar(n).toLowerCase() = "o" and
// e.g. 2^32 - 1 = "37777777777"
@@ -1163,14 +1266,16 @@ class FormatLiteral extends Literal {
(
if this.hasAlternateFlag(n) then len = 1 + baseLen else len = baseLen // "0"
)
)
) and
reason = TTypeBoundsAnalysis()
or
this.getConversionChar(n).toLowerCase() = "s" and
len =
min(int v |
v = this.getPrecision(n) or
v = this.getUse().getFormatArgument(n).(AnalysedString).getMaxLength() - 1 // (don't count null terminator)
)
) and
reason = TValueFlowAnalysis()
)
)
}
@@ -1182,10 +1287,19 @@ class FormatLiteral extends Literal {
* determining whether a buffer overflow is caused by long float to string
* conversions.
*/
int getMaxConvertedLengthLimited(int n) {
int getMaxConvertedLengthLimited(int n) { result = max(getMaxConvertedLengthLimited(n, _)) }
/**
* Gets the maximum length of the string that can be produced by the nth
* conversion specifier of this format string, specifying the reason for the
* estimation, except that float to string conversions are assumed to be 8
* characters. This is helpful for determining whether a buffer overflow is
* caused by long float to string conversions.
*/
int getMaxConvertedLengthLimited(int n, BufferWriteEstimationReason reason) {
if this.getConversionChar(n).toLowerCase() = "f"
then result = this.getMaxConvertedLength(n).minimum(8)
else result = this.getMaxConvertedLength(n)
then result = this.getMaxConvertedLength(n, reason).minimum(8)
else result = this.getMaxConvertedLength(n, reason)
}
/**
@@ -1225,29 +1339,35 @@ class FormatLiteral extends Literal {
)
}
private int getMaxConvertedLengthAfter(int n) {
private int getMaxConvertedLengthAfter(int n, BufferWriteEstimationReason reason) {
if n = this.getNumConvSpec()
then result = this.getConstantSuffix().length() + 1
then result = this.getConstantSuffix().length() + 1 and reason = TValueFlowAnalysis()
else
result =
this.getConstantPart(n).length() + this.getMaxConvertedLength(n) +
this.getMaxConvertedLengthAfter(n + 1)
exists(BufferWriteEstimationReason headReason, BufferWriteEstimationReason tailReason |
result =
this.getConstantPart(n).length() + this.getMaxConvertedLength(n, headReason) +
this.getMaxConvertedLengthAfter(n + 1, tailReason) and
reason = headReason.combineWith(tailReason)
)
}
private int getMaxConvertedLengthAfterLimited(int n) {
private int getMaxConvertedLengthAfterLimited(int n, BufferWriteEstimationReason reason) {
if n = this.getNumConvSpec()
then result = this.getConstantSuffix().length() + 1
then result = this.getConstantSuffix().length() + 1 and reason = TValueFlowAnalysis()
else
result =
this.getConstantPart(n).length() + this.getMaxConvertedLengthLimited(n) +
this.getMaxConvertedLengthAfterLimited(n + 1)
exists(BufferWriteEstimationReason headReason, BufferWriteEstimationReason tailReason |
result =
this.getConstantPart(n).length() + this.getMaxConvertedLengthLimited(n, headReason) +
this.getMaxConvertedLengthAfterLimited(n + 1, tailReason) and
reason = headReason.combineWith(tailReason)
)
}
/**
* Gets the maximum length of the string that can be produced by this format
* string. Has no result if this cannot be determined.
*/
int getMaxConvertedLength() { result = this.getMaxConvertedLengthAfter(0) }
int getMaxConvertedLength() { result = this.getMaxConvertedLengthAfter(0, _) }
/**
* Gets the maximum length of the string that can be produced by this format
@@ -1255,5 +1375,24 @@ class FormatLiteral extends Literal {
* characters. This is helpful for determining whether a buffer overflow
* is caused by long float to string conversions.
*/
int getMaxConvertedLengthLimited() { result = this.getMaxConvertedLengthAfterLimited(0) }
int getMaxConvertedLengthLimited() { result = this.getMaxConvertedLengthAfterLimited(0, _) }
/**
* Gets the maximum length of the string that can be produced by this format
* string, specifying the reason for the estimate. Has no result if no estimate
* can be found.
*/
int getMaxConvertedLengthWithReason(BufferWriteEstimationReason reason) {
result = this.getMaxConvertedLengthAfter(0, reason)
}
/**
* Gets the maximum length of the string that can be produced by this format
* string, specifying the reason for the estimate, except that float to string
* conversions are assumed to be 8 characters. This is helpful for determining
* whether a buffer overflow is caused by long float to string conversions.
*/
int getMaxConvertedLengthLimitedWithReason(BufferWriteEstimationReason reason) {
result = this.getMaxConvertedLengthAfterLimited(0, reason)
}
}

View File

@@ -1,4 +1,6 @@
private import cpp
private import semmle.code.cpp.dataflow.internal.DataFlowPrivate
private import semmle.code.cpp.dataflow.internal.DataFlowUtil
/**
* Gets a function that might be called by `call`.
@@ -63,3 +65,17 @@ predicate mayBenefitFromCallContext(Call call, Function f) { none() }
* restricted to those `call`s for which a context might make a difference.
*/
Function viableImplInCallContext(Call call, Call ctx) { none() }
/** A parameter position represented by an integer. */
class ParameterPosition extends int {
ParameterPosition() { any(ParameterNode p).isParameterOf(_, this) }
}
/** An argument position represented by an integer. */
class ArgumentPosition extends int {
ArgumentPosition() { any(ArgumentNode a).argumentOf(_, this) }
}
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
pragma[inline]
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos }

View File

@@ -256,11 +256,11 @@ private class ArgNodeEx extends NodeEx {
private class ParamNodeEx extends NodeEx {
ParamNodeEx() { this.asNode() instanceof ParamNode }
predicate isParameterOf(DataFlowCallable c, int i) {
this.asNode().(ParamNode).isParameterOf(c, i)
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.asNode().(ParamNode).isParameterOf(c, pos)
}
int getPosition() { this.isParameterOf(_, result) }
ParameterPosition getPosition() { this.isParameterOf(_, result) }
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
@@ -1447,7 +1447,7 @@ private module Stage2 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2142,7 +2142,7 @@ private module Stage3 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2908,7 +2908,7 @@ private module Stage4 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2992,7 +2992,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
int getParameterPos() { p.isParameterOf(_, result) }
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
ParamNodeEx getParamNode() { result = p }
@@ -3639,39 +3639,40 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
Configuration config
PathNodeMid mid, ParameterPosition ppos, CallContext cc, DataFlowCall call, AccessPath ap,
AccessPathApprox apa, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
apa = ap.getApprox() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config
) {
exists(ParamNodeEx p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
p.isParameterOf(callable, pos)
)
}
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
AccessPath ap, Configuration config
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
pathIntoArg(mid, pragma[only_bind_into](pos), outercc, call, ap, pragma[only_bind_into](apa),
pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa),
pragma[only_bind_into](config))
)
}
@@ -3686,9 +3687,9 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
(
sc = TSummaryCtxSome(p, ap)
or
@@ -3712,7 +3713,7 @@ private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa,
Configuration config
) {
exists(PathNodeMid mid, RetNodeEx ret, int pos |
exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos |
mid.getNodeEx() = ret and
kind = ret.getKind() and
cc = mid.getCallContext() and
@@ -4441,24 +4442,25 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
PartialPathNodeFwd mid, ParameterPosition ppos, CallContext cc, DataFlowCall call,
PartialAccessPath ap, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc,
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, ap, config) and
partialPathIntoArg(mid, pos, outercc, call, ap, config) and
callable = resolveCall(call, outercc)
}
@@ -4467,9 +4469,9 @@ private module FlowExploration {
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
@@ -4633,22 +4635,23 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathFlowsThrough(
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
ArgumentPosition apos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2,
RevPartialAccessPath ap, Configuration config
) {
exists(PartialPathNodeRev mid, ParamNodeEx p |
exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos |
mid.getNodeEx() = p and
p.getPosition() = pos and
p.getPosition() = ppos and
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate revPartialPathThroughCallable0(
DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap,
DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, RevPartialAccessPath ap,
Configuration config
) {
exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 |
@@ -4661,7 +4664,7 @@ private module FlowExploration {
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
exists(DataFlowCall call, ArgumentPosition pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
node.asNode().(ArgNode).argumentOf(call, pos)
)

View File

@@ -256,11 +256,11 @@ private class ArgNodeEx extends NodeEx {
private class ParamNodeEx extends NodeEx {
ParamNodeEx() { this.asNode() instanceof ParamNode }
predicate isParameterOf(DataFlowCallable c, int i) {
this.asNode().(ParamNode).isParameterOf(c, i)
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.asNode().(ParamNode).isParameterOf(c, pos)
}
int getPosition() { this.isParameterOf(_, result) }
ParameterPosition getPosition() { this.isParameterOf(_, result) }
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
@@ -1447,7 +1447,7 @@ private module Stage2 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2142,7 +2142,7 @@ private module Stage3 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2908,7 +2908,7 @@ private module Stage4 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2992,7 +2992,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
int getParameterPos() { p.isParameterOf(_, result) }
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
ParamNodeEx getParamNode() { result = p }
@@ -3639,39 +3639,40 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
Configuration config
PathNodeMid mid, ParameterPosition ppos, CallContext cc, DataFlowCall call, AccessPath ap,
AccessPathApprox apa, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
apa = ap.getApprox() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config
) {
exists(ParamNodeEx p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
p.isParameterOf(callable, pos)
)
}
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
AccessPath ap, Configuration config
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
pathIntoArg(mid, pragma[only_bind_into](pos), outercc, call, ap, pragma[only_bind_into](apa),
pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa),
pragma[only_bind_into](config))
)
}
@@ -3686,9 +3687,9 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
(
sc = TSummaryCtxSome(p, ap)
or
@@ -3712,7 +3713,7 @@ private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa,
Configuration config
) {
exists(PathNodeMid mid, RetNodeEx ret, int pos |
exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos |
mid.getNodeEx() = ret and
kind = ret.getKind() and
cc = mid.getCallContext() and
@@ -4441,24 +4442,25 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
PartialPathNodeFwd mid, ParameterPosition ppos, CallContext cc, DataFlowCall call,
PartialAccessPath ap, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc,
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, ap, config) and
partialPathIntoArg(mid, pos, outercc, call, ap, config) and
callable = resolveCall(call, outercc)
}
@@ -4467,9 +4469,9 @@ private module FlowExploration {
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
@@ -4633,22 +4635,23 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathFlowsThrough(
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
ArgumentPosition apos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2,
RevPartialAccessPath ap, Configuration config
) {
exists(PartialPathNodeRev mid, ParamNodeEx p |
exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos |
mid.getNodeEx() = p and
p.getPosition() = pos and
p.getPosition() = ppos and
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate revPartialPathThroughCallable0(
DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap,
DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, RevPartialAccessPath ap,
Configuration config
) {
exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 |
@@ -4661,7 +4664,7 @@ private module FlowExploration {
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
exists(DataFlowCall call, ArgumentPosition pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
node.asNode().(ArgNode).argumentOf(call, pos)
)

View File

@@ -256,11 +256,11 @@ private class ArgNodeEx extends NodeEx {
private class ParamNodeEx extends NodeEx {
ParamNodeEx() { this.asNode() instanceof ParamNode }
predicate isParameterOf(DataFlowCallable c, int i) {
this.asNode().(ParamNode).isParameterOf(c, i)
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.asNode().(ParamNode).isParameterOf(c, pos)
}
int getPosition() { this.isParameterOf(_, result) }
ParameterPosition getPosition() { this.isParameterOf(_, result) }
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
@@ -1447,7 +1447,7 @@ private module Stage2 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2142,7 +2142,7 @@ private module Stage3 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2908,7 +2908,7 @@ private module Stage4 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2992,7 +2992,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
int getParameterPos() { p.isParameterOf(_, result) }
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
ParamNodeEx getParamNode() { result = p }
@@ -3639,39 +3639,40 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
Configuration config
PathNodeMid mid, ParameterPosition ppos, CallContext cc, DataFlowCall call, AccessPath ap,
AccessPathApprox apa, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
apa = ap.getApprox() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config
) {
exists(ParamNodeEx p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
p.isParameterOf(callable, pos)
)
}
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
AccessPath ap, Configuration config
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
pathIntoArg(mid, pragma[only_bind_into](pos), outercc, call, ap, pragma[only_bind_into](apa),
pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa),
pragma[only_bind_into](config))
)
}
@@ -3686,9 +3687,9 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
(
sc = TSummaryCtxSome(p, ap)
or
@@ -3712,7 +3713,7 @@ private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa,
Configuration config
) {
exists(PathNodeMid mid, RetNodeEx ret, int pos |
exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos |
mid.getNodeEx() = ret and
kind = ret.getKind() and
cc = mid.getCallContext() and
@@ -4441,24 +4442,25 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
PartialPathNodeFwd mid, ParameterPosition ppos, CallContext cc, DataFlowCall call,
PartialAccessPath ap, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc,
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, ap, config) and
partialPathIntoArg(mid, pos, outercc, call, ap, config) and
callable = resolveCall(call, outercc)
}
@@ -4467,9 +4469,9 @@ private module FlowExploration {
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
@@ -4633,22 +4635,23 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathFlowsThrough(
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
ArgumentPosition apos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2,
RevPartialAccessPath ap, Configuration config
) {
exists(PartialPathNodeRev mid, ParamNodeEx p |
exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos |
mid.getNodeEx() = p and
p.getPosition() = pos and
p.getPosition() = ppos and
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate revPartialPathThroughCallable0(
DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap,
DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, RevPartialAccessPath ap,
Configuration config
) {
exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 |
@@ -4661,7 +4664,7 @@ private module FlowExploration {
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
exists(DataFlowCall call, ArgumentPosition pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
node.asNode().(ArgNode).argumentOf(call, pos)
)

View File

@@ -256,11 +256,11 @@ private class ArgNodeEx extends NodeEx {
private class ParamNodeEx extends NodeEx {
ParamNodeEx() { this.asNode() instanceof ParamNode }
predicate isParameterOf(DataFlowCallable c, int i) {
this.asNode().(ParamNode).isParameterOf(c, i)
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.asNode().(ParamNode).isParameterOf(c, pos)
}
int getPosition() { this.isParameterOf(_, result) }
ParameterPosition getPosition() { this.isParameterOf(_, result) }
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
@@ -1447,7 +1447,7 @@ private module Stage2 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2142,7 +2142,7 @@ private module Stage3 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2908,7 +2908,7 @@ private module Stage4 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2992,7 +2992,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
int getParameterPos() { p.isParameterOf(_, result) }
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
ParamNodeEx getParamNode() { result = p }
@@ -3639,39 +3639,40 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
Configuration config
PathNodeMid mid, ParameterPosition ppos, CallContext cc, DataFlowCall call, AccessPath ap,
AccessPathApprox apa, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
apa = ap.getApprox() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config
) {
exists(ParamNodeEx p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
p.isParameterOf(callable, pos)
)
}
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
AccessPath ap, Configuration config
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
pathIntoArg(mid, pragma[only_bind_into](pos), outercc, call, ap, pragma[only_bind_into](apa),
pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa),
pragma[only_bind_into](config))
)
}
@@ -3686,9 +3687,9 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
(
sc = TSummaryCtxSome(p, ap)
or
@@ -3712,7 +3713,7 @@ private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa,
Configuration config
) {
exists(PathNodeMid mid, RetNodeEx ret, int pos |
exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos |
mid.getNodeEx() = ret and
kind = ret.getKind() and
cc = mid.getCallContext() and
@@ -4441,24 +4442,25 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
PartialPathNodeFwd mid, ParameterPosition ppos, CallContext cc, DataFlowCall call,
PartialAccessPath ap, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc,
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, ap, config) and
partialPathIntoArg(mid, pos, outercc, call, ap, config) and
callable = resolveCall(call, outercc)
}
@@ -4467,9 +4469,9 @@ private module FlowExploration {
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
@@ -4633,22 +4635,23 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathFlowsThrough(
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
ArgumentPosition apos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2,
RevPartialAccessPath ap, Configuration config
) {
exists(PartialPathNodeRev mid, ParamNodeEx p |
exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos |
mid.getNodeEx() = p and
p.getPosition() = pos and
p.getPosition() = ppos and
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate revPartialPathThroughCallable0(
DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap,
DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, RevPartialAccessPath ap,
Configuration config
) {
exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 |
@@ -4661,7 +4664,7 @@ private module FlowExploration {
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
exists(DataFlowCall call, ArgumentPosition pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
node.asNode().(ArgNode).argumentOf(call, pos)
)

View File

@@ -62,6 +62,18 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) {
tupleLimit = 1000
}
/**
* Holds if `arg` is an argument of `call` with an argument position that matches
* parameter position `ppos`.
*/
pragma[noinline]
predicate argumentPositionMatch(DataFlowCall call, ArgNode arg, ParameterPosition ppos) {
exists(ArgumentPosition apos |
arg.argumentOf(call, apos) and
parameterMatch(ppos, apos)
)
}
/**
* Provides a simple data-flow analysis for resolving lambda calls. The analysis
* currently excludes read-steps, store-steps, and flow-through.
@@ -71,25 +83,27 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) {
* calls. For this reason, we cannot reuse the code from `DataFlowImpl.qll` directly.
*/
private module LambdaFlow {
private predicate viableParamNonLambda(DataFlowCall call, int i, ParamNode p) {
p.isParameterOf(viableCallable(call), i)
pragma[noinline]
private predicate viableParamNonLambda(DataFlowCall call, ParameterPosition ppos, ParamNode p) {
p.isParameterOf(viableCallable(call), ppos)
}
private predicate viableParamLambda(DataFlowCall call, int i, ParamNode p) {
p.isParameterOf(viableCallableLambda(call, _), i)
pragma[noinline]
private predicate viableParamLambda(DataFlowCall call, ParameterPosition ppos, ParamNode p) {
p.isParameterOf(viableCallableLambda(call, _), ppos)
}
private predicate viableParamArgNonLambda(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(int i |
viableParamNonLambda(call, i, p) and
arg.argumentOf(call, i)
exists(ParameterPosition ppos |
viableParamNonLambda(call, ppos, p) and
argumentPositionMatch(call, arg, ppos)
)
}
private predicate viableParamArgLambda(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(int i |
viableParamLambda(call, i, p) and
arg.argumentOf(call, i)
exists(ParameterPosition ppos |
viableParamLambda(call, ppos, p) and
argumentPositionMatch(call, arg, ppos)
)
}
@@ -322,7 +336,7 @@ private module Cached {
or
exists(ArgNode arg |
result.(PostUpdateNode).getPreUpdateNode() = arg and
arg.argumentOf(call, k.(ParamUpdateReturnKind).getPosition())
arg.argumentOf(call, k.(ParamUpdateReturnKind).getAMatchingArgumentPosition())
)
}
@@ -330,7 +344,7 @@ private module Cached {
predicate returnNodeExt(Node n, ReturnKindExt k) {
k = TValueReturn(n.(ReturnNode).getKind())
or
exists(ParamNode p, int pos |
exists(ParamNode p, ParameterPosition pos |
parameterValueFlowsToPreUpdate(p, n) and
p.isParameterOf(_, pos) and
k = TParamUpdate(pos)
@@ -352,11 +366,13 @@ private module Cached {
}
cached
predicate parameterNode(Node p, DataFlowCallable c, int pos) { isParameterNode(p, c, pos) }
predicate parameterNode(Node p, DataFlowCallable c, ParameterPosition pos) {
isParameterNode(p, c, pos)
}
cached
predicate argumentNode(Node n, DataFlowCall call, int pos) {
n.(ArgumentNode).argumentOf(call, pos)
predicate argumentNode(Node n, DataFlowCall call, ArgumentPosition pos) {
isArgumentNode(n, call, pos)
}
/**
@@ -374,12 +390,12 @@ private module Cached {
}
/**
* Holds if `p` is the `i`th parameter of a viable dispatch target of `call`.
* The instance parameter is considered to have index `-1`.
* Holds if `p` is the parameter of a viable dispatch target of `call`,
* and `p` has position `ppos`.
*/
pragma[nomagic]
private predicate viableParam(DataFlowCall call, int i, ParamNode p) {
p.isParameterOf(viableCallableExt(call), i)
private predicate viableParam(DataFlowCall call, ParameterPosition ppos, ParamNode p) {
p.isParameterOf(viableCallableExt(call), ppos)
}
/**
@@ -388,9 +404,9 @@ private module Cached {
*/
cached
predicate viableParamArg(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(int i |
viableParam(call, i, p) and
arg.argumentOf(call, i) and
exists(ParameterPosition ppos |
viableParam(call, ppos, p) and
argumentPositionMatch(call, arg, ppos) and
compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p))
)
}
@@ -862,7 +878,7 @@ private module Cached {
cached
newtype TReturnKindExt =
TValueReturn(ReturnKind kind) or
TParamUpdate(int pos) { exists(ParamNode p | p.isParameterOf(_, pos)) }
TParamUpdate(ParameterPosition pos) { exists(ParamNode p | p.isParameterOf(_, pos)) }
cached
newtype TBooleanOption =
@@ -1054,9 +1070,9 @@ class ParamNode extends Node {
/**
* Holds if this node is the parameter of callable `c` at the specified
* (zero-based) position.
* position.
*/
predicate isParameterOf(DataFlowCallable c, int i) { parameterNode(this, c, i) }
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { parameterNode(this, c, pos) }
}
/** A data-flow node that represents a call argument. */
@@ -1064,7 +1080,9 @@ class ArgNode extends Node {
ArgNode() { argumentNode(this, _, _) }
/** Holds if this argument occurs at the given position in the given call. */
final predicate argumentOf(DataFlowCall call, int pos) { argumentNode(this, call, pos) }
final predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
argumentNode(this, call, pos)
}
}
/**
@@ -1110,11 +1128,14 @@ class ValueReturnKind extends ReturnKindExt, TValueReturn {
}
class ParamUpdateReturnKind extends ReturnKindExt, TParamUpdate {
private int pos;
private ParameterPosition pos;
ParamUpdateReturnKind() { this = TParamUpdate(pos) }
int getPosition() { result = pos }
ParameterPosition getPosition() { result = pos }
pragma[nomagic]
ArgumentPosition getAMatchingArgumentPosition() { parameterMatch(pos, result) }
override string toString() { result = "param update " + pos }
}

View File

@@ -256,11 +256,11 @@ private class ArgNodeEx extends NodeEx {
private class ParamNodeEx extends NodeEx {
ParamNodeEx() { this.asNode() instanceof ParamNode }
predicate isParameterOf(DataFlowCallable c, int i) {
this.asNode().(ParamNode).isParameterOf(c, i)
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.asNode().(ParamNode).isParameterOf(c, pos)
}
int getPosition() { this.isParameterOf(_, result) }
ParameterPosition getPosition() { this.isParameterOf(_, result) }
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
@@ -1447,7 +1447,7 @@ private module Stage2 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2142,7 +2142,7 @@ private module Stage3 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2908,7 +2908,7 @@ private module Stage4 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2992,7 +2992,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
int getParameterPos() { p.isParameterOf(_, result) }
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
ParamNodeEx getParamNode() { result = p }
@@ -3639,39 +3639,40 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
Configuration config
PathNodeMid mid, ParameterPosition ppos, CallContext cc, DataFlowCall call, AccessPath ap,
AccessPathApprox apa, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
apa = ap.getApprox() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config
) {
exists(ParamNodeEx p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
p.isParameterOf(callable, pos)
)
}
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
AccessPath ap, Configuration config
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
pathIntoArg(mid, pragma[only_bind_into](pos), outercc, call, ap, pragma[only_bind_into](apa),
pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa),
pragma[only_bind_into](config))
)
}
@@ -3686,9 +3687,9 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
(
sc = TSummaryCtxSome(p, ap)
or
@@ -3712,7 +3713,7 @@ private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa,
Configuration config
) {
exists(PathNodeMid mid, RetNodeEx ret, int pos |
exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos |
mid.getNodeEx() = ret and
kind = ret.getKind() and
cc = mid.getCallContext() and
@@ -4441,24 +4442,25 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
PartialPathNodeFwd mid, ParameterPosition ppos, CallContext cc, DataFlowCall call,
PartialAccessPath ap, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc,
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, ap, config) and
partialPathIntoArg(mid, pos, outercc, call, ap, config) and
callable = resolveCall(call, outercc)
}
@@ -4467,9 +4469,9 @@ private module FlowExploration {
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
@@ -4633,22 +4635,23 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathFlowsThrough(
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
ArgumentPosition apos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2,
RevPartialAccessPath ap, Configuration config
) {
exists(PartialPathNodeRev mid, ParamNodeEx p |
exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos |
mid.getNodeEx() = p and
p.getPosition() = pos and
p.getPosition() = ppos and
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate revPartialPathThroughCallable0(
DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap,
DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, RevPartialAccessPath ap,
Configuration config
) {
exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 |
@@ -4661,7 +4664,7 @@ private module FlowExploration {
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
exists(DataFlowCall call, ArgumentPosition pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
node.asNode().(ArgNode).argumentOf(call, pos)
)

View File

@@ -8,7 +8,14 @@ private import DataFlowImplConsistency
DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() }
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
predicate isParameterNode(ParameterNode p, DataFlowCallable c, int pos) { p.isParameterOf(c, pos) }
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) {
p.isParameterOf(c, pos)
}
/** Holds if `arg` is an `ArgumentNode` of `c` with position `pos`. */
predicate isArgumentNode(ArgumentNode arg, DataFlowCall c, ArgumentPosition pos) {
arg.argumentOf(c, pos)
}
/** Gets the instance argument of a non-static call. */
private Node getInstanceArgument(Call call) {

View File

@@ -2,6 +2,7 @@ private import cpp
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import DataFlowImplCommon as DataFlowImplCommon
/**
@@ -266,3 +267,17 @@ Function viableImplInCallContext(CallInstruction call, CallInstruction ctx) {
result = ctx.getArgument(i).getUnconvertedResultExpression().(FunctionAccess).getTarget()
)
}
/** A parameter position represented by an integer. */
class ParameterPosition extends int {
ParameterPosition() { any(ParameterNode p).isParameterOf(_, this) }
}
/** An argument position represented by an integer. */
class ArgumentPosition extends int {
ArgumentPosition() { any(ArgumentNode a).argumentOf(_, this) }
}
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
pragma[inline]
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos }

View File

@@ -256,11 +256,11 @@ private class ArgNodeEx extends NodeEx {
private class ParamNodeEx extends NodeEx {
ParamNodeEx() { this.asNode() instanceof ParamNode }
predicate isParameterOf(DataFlowCallable c, int i) {
this.asNode().(ParamNode).isParameterOf(c, i)
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.asNode().(ParamNode).isParameterOf(c, pos)
}
int getPosition() { this.isParameterOf(_, result) }
ParameterPosition getPosition() { this.isParameterOf(_, result) }
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
@@ -1447,7 +1447,7 @@ private module Stage2 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2142,7 +2142,7 @@ private module Stage3 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2908,7 +2908,7 @@ private module Stage4 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2992,7 +2992,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
int getParameterPos() { p.isParameterOf(_, result) }
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
ParamNodeEx getParamNode() { result = p }
@@ -3639,39 +3639,40 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
Configuration config
PathNodeMid mid, ParameterPosition ppos, CallContext cc, DataFlowCall call, AccessPath ap,
AccessPathApprox apa, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
apa = ap.getApprox() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config
) {
exists(ParamNodeEx p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
p.isParameterOf(callable, pos)
)
}
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
AccessPath ap, Configuration config
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
pathIntoArg(mid, pragma[only_bind_into](pos), outercc, call, ap, pragma[only_bind_into](apa),
pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa),
pragma[only_bind_into](config))
)
}
@@ -3686,9 +3687,9 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
(
sc = TSummaryCtxSome(p, ap)
or
@@ -3712,7 +3713,7 @@ private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa,
Configuration config
) {
exists(PathNodeMid mid, RetNodeEx ret, int pos |
exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos |
mid.getNodeEx() = ret and
kind = ret.getKind() and
cc = mid.getCallContext() and
@@ -4441,24 +4442,25 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
PartialPathNodeFwd mid, ParameterPosition ppos, CallContext cc, DataFlowCall call,
PartialAccessPath ap, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc,
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, ap, config) and
partialPathIntoArg(mid, pos, outercc, call, ap, config) and
callable = resolveCall(call, outercc)
}
@@ -4467,9 +4469,9 @@ private module FlowExploration {
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
@@ -4633,22 +4635,23 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathFlowsThrough(
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
ArgumentPosition apos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2,
RevPartialAccessPath ap, Configuration config
) {
exists(PartialPathNodeRev mid, ParamNodeEx p |
exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos |
mid.getNodeEx() = p and
p.getPosition() = pos and
p.getPosition() = ppos and
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate revPartialPathThroughCallable0(
DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap,
DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, RevPartialAccessPath ap,
Configuration config
) {
exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 |
@@ -4661,7 +4664,7 @@ private module FlowExploration {
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
exists(DataFlowCall call, ArgumentPosition pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
node.asNode().(ArgNode).argumentOf(call, pos)
)

View File

@@ -256,11 +256,11 @@ private class ArgNodeEx extends NodeEx {
private class ParamNodeEx extends NodeEx {
ParamNodeEx() { this.asNode() instanceof ParamNode }
predicate isParameterOf(DataFlowCallable c, int i) {
this.asNode().(ParamNode).isParameterOf(c, i)
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.asNode().(ParamNode).isParameterOf(c, pos)
}
int getPosition() { this.isParameterOf(_, result) }
ParameterPosition getPosition() { this.isParameterOf(_, result) }
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
@@ -1447,7 +1447,7 @@ private module Stage2 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2142,7 +2142,7 @@ private module Stage3 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2908,7 +2908,7 @@ private module Stage4 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2992,7 +2992,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
int getParameterPos() { p.isParameterOf(_, result) }
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
ParamNodeEx getParamNode() { result = p }
@@ -3639,39 +3639,40 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
Configuration config
PathNodeMid mid, ParameterPosition ppos, CallContext cc, DataFlowCall call, AccessPath ap,
AccessPathApprox apa, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
apa = ap.getApprox() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config
) {
exists(ParamNodeEx p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
p.isParameterOf(callable, pos)
)
}
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
AccessPath ap, Configuration config
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
pathIntoArg(mid, pragma[only_bind_into](pos), outercc, call, ap, pragma[only_bind_into](apa),
pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa),
pragma[only_bind_into](config))
)
}
@@ -3686,9 +3687,9 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
(
sc = TSummaryCtxSome(p, ap)
or
@@ -3712,7 +3713,7 @@ private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa,
Configuration config
) {
exists(PathNodeMid mid, RetNodeEx ret, int pos |
exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos |
mid.getNodeEx() = ret and
kind = ret.getKind() and
cc = mid.getCallContext() and
@@ -4441,24 +4442,25 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
PartialPathNodeFwd mid, ParameterPosition ppos, CallContext cc, DataFlowCall call,
PartialAccessPath ap, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc,
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, ap, config) and
partialPathIntoArg(mid, pos, outercc, call, ap, config) and
callable = resolveCall(call, outercc)
}
@@ -4467,9 +4469,9 @@ private module FlowExploration {
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
@@ -4633,22 +4635,23 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathFlowsThrough(
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
ArgumentPosition apos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2,
RevPartialAccessPath ap, Configuration config
) {
exists(PartialPathNodeRev mid, ParamNodeEx p |
exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos |
mid.getNodeEx() = p and
p.getPosition() = pos and
p.getPosition() = ppos and
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate revPartialPathThroughCallable0(
DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap,
DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, RevPartialAccessPath ap,
Configuration config
) {
exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 |
@@ -4661,7 +4664,7 @@ private module FlowExploration {
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
exists(DataFlowCall call, ArgumentPosition pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
node.asNode().(ArgNode).argumentOf(call, pos)
)

View File

@@ -256,11 +256,11 @@ private class ArgNodeEx extends NodeEx {
private class ParamNodeEx extends NodeEx {
ParamNodeEx() { this.asNode() instanceof ParamNode }
predicate isParameterOf(DataFlowCallable c, int i) {
this.asNode().(ParamNode).isParameterOf(c, i)
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.asNode().(ParamNode).isParameterOf(c, pos)
}
int getPosition() { this.isParameterOf(_, result) }
ParameterPosition getPosition() { this.isParameterOf(_, result) }
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
@@ -1447,7 +1447,7 @@ private module Stage2 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2142,7 +2142,7 @@ private module Stage3 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2908,7 +2908,7 @@ private module Stage4 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2992,7 +2992,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
int getParameterPos() { p.isParameterOf(_, result) }
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
ParamNodeEx getParamNode() { result = p }
@@ -3639,39 +3639,40 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
Configuration config
PathNodeMid mid, ParameterPosition ppos, CallContext cc, DataFlowCall call, AccessPath ap,
AccessPathApprox apa, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
apa = ap.getApprox() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config
) {
exists(ParamNodeEx p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
p.isParameterOf(callable, pos)
)
}
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
AccessPath ap, Configuration config
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
pathIntoArg(mid, pragma[only_bind_into](pos), outercc, call, ap, pragma[only_bind_into](apa),
pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa),
pragma[only_bind_into](config))
)
}
@@ -3686,9 +3687,9 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
(
sc = TSummaryCtxSome(p, ap)
or
@@ -3712,7 +3713,7 @@ private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa,
Configuration config
) {
exists(PathNodeMid mid, RetNodeEx ret, int pos |
exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos |
mid.getNodeEx() = ret and
kind = ret.getKind() and
cc = mid.getCallContext() and
@@ -4441,24 +4442,25 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
PartialPathNodeFwd mid, ParameterPosition ppos, CallContext cc, DataFlowCall call,
PartialAccessPath ap, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc,
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, ap, config) and
partialPathIntoArg(mid, pos, outercc, call, ap, config) and
callable = resolveCall(call, outercc)
}
@@ -4467,9 +4469,9 @@ private module FlowExploration {
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
@@ -4633,22 +4635,23 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathFlowsThrough(
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
ArgumentPosition apos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2,
RevPartialAccessPath ap, Configuration config
) {
exists(PartialPathNodeRev mid, ParamNodeEx p |
exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos |
mid.getNodeEx() = p and
p.getPosition() = pos and
p.getPosition() = ppos and
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate revPartialPathThroughCallable0(
DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap,
DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, RevPartialAccessPath ap,
Configuration config
) {
exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 |
@@ -4661,7 +4664,7 @@ private module FlowExploration {
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
exists(DataFlowCall call, ArgumentPosition pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
node.asNode().(ArgNode).argumentOf(call, pos)
)

View File

@@ -256,11 +256,11 @@ private class ArgNodeEx extends NodeEx {
private class ParamNodeEx extends NodeEx {
ParamNodeEx() { this.asNode() instanceof ParamNode }
predicate isParameterOf(DataFlowCallable c, int i) {
this.asNode().(ParamNode).isParameterOf(c, i)
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.asNode().(ParamNode).isParameterOf(c, pos)
}
int getPosition() { this.isParameterOf(_, result) }
ParameterPosition getPosition() { this.isParameterOf(_, result) }
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
@@ -1447,7 +1447,7 @@ private module Stage2 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2142,7 +2142,7 @@ private module Stage3 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2908,7 +2908,7 @@ private module Stage4 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2992,7 +2992,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
int getParameterPos() { p.isParameterOf(_, result) }
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
ParamNodeEx getParamNode() { result = p }
@@ -3639,39 +3639,40 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
Configuration config
PathNodeMid mid, ParameterPosition ppos, CallContext cc, DataFlowCall call, AccessPath ap,
AccessPathApprox apa, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
apa = ap.getApprox() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config
) {
exists(ParamNodeEx p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
p.isParameterOf(callable, pos)
)
}
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
AccessPath ap, Configuration config
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
pathIntoArg(mid, pragma[only_bind_into](pos), outercc, call, ap, pragma[only_bind_into](apa),
pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa),
pragma[only_bind_into](config))
)
}
@@ -3686,9 +3687,9 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
(
sc = TSummaryCtxSome(p, ap)
or
@@ -3712,7 +3713,7 @@ private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa,
Configuration config
) {
exists(PathNodeMid mid, RetNodeEx ret, int pos |
exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos |
mid.getNodeEx() = ret and
kind = ret.getKind() and
cc = mid.getCallContext() and
@@ -4441,24 +4442,25 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
PartialPathNodeFwd mid, ParameterPosition ppos, CallContext cc, DataFlowCall call,
PartialAccessPath ap, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc,
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, ap, config) and
partialPathIntoArg(mid, pos, outercc, call, ap, config) and
callable = resolveCall(call, outercc)
}
@@ -4467,9 +4469,9 @@ private module FlowExploration {
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
@@ -4633,22 +4635,23 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathFlowsThrough(
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
ArgumentPosition apos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2,
RevPartialAccessPath ap, Configuration config
) {
exists(PartialPathNodeRev mid, ParamNodeEx p |
exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos |
mid.getNodeEx() = p and
p.getPosition() = pos and
p.getPosition() = ppos and
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate revPartialPathThroughCallable0(
DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap,
DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, RevPartialAccessPath ap,
Configuration config
) {
exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 |
@@ -4661,7 +4664,7 @@ private module FlowExploration {
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
exists(DataFlowCall call, ArgumentPosition pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
node.asNode().(ArgNode).argumentOf(call, pos)
)

View File

@@ -62,6 +62,18 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) {
tupleLimit = 1000
}
/**
* Holds if `arg` is an argument of `call` with an argument position that matches
* parameter position `ppos`.
*/
pragma[noinline]
predicate argumentPositionMatch(DataFlowCall call, ArgNode arg, ParameterPosition ppos) {
exists(ArgumentPosition apos |
arg.argumentOf(call, apos) and
parameterMatch(ppos, apos)
)
}
/**
* Provides a simple data-flow analysis for resolving lambda calls. The analysis
* currently excludes read-steps, store-steps, and flow-through.
@@ -71,25 +83,27 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) {
* calls. For this reason, we cannot reuse the code from `DataFlowImpl.qll` directly.
*/
private module LambdaFlow {
private predicate viableParamNonLambda(DataFlowCall call, int i, ParamNode p) {
p.isParameterOf(viableCallable(call), i)
pragma[noinline]
private predicate viableParamNonLambda(DataFlowCall call, ParameterPosition ppos, ParamNode p) {
p.isParameterOf(viableCallable(call), ppos)
}
private predicate viableParamLambda(DataFlowCall call, int i, ParamNode p) {
p.isParameterOf(viableCallableLambda(call, _), i)
pragma[noinline]
private predicate viableParamLambda(DataFlowCall call, ParameterPosition ppos, ParamNode p) {
p.isParameterOf(viableCallableLambda(call, _), ppos)
}
private predicate viableParamArgNonLambda(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(int i |
viableParamNonLambda(call, i, p) and
arg.argumentOf(call, i)
exists(ParameterPosition ppos |
viableParamNonLambda(call, ppos, p) and
argumentPositionMatch(call, arg, ppos)
)
}
private predicate viableParamArgLambda(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(int i |
viableParamLambda(call, i, p) and
arg.argumentOf(call, i)
exists(ParameterPosition ppos |
viableParamLambda(call, ppos, p) and
argumentPositionMatch(call, arg, ppos)
)
}
@@ -322,7 +336,7 @@ private module Cached {
or
exists(ArgNode arg |
result.(PostUpdateNode).getPreUpdateNode() = arg and
arg.argumentOf(call, k.(ParamUpdateReturnKind).getPosition())
arg.argumentOf(call, k.(ParamUpdateReturnKind).getAMatchingArgumentPosition())
)
}
@@ -330,7 +344,7 @@ private module Cached {
predicate returnNodeExt(Node n, ReturnKindExt k) {
k = TValueReturn(n.(ReturnNode).getKind())
or
exists(ParamNode p, int pos |
exists(ParamNode p, ParameterPosition pos |
parameterValueFlowsToPreUpdate(p, n) and
p.isParameterOf(_, pos) and
k = TParamUpdate(pos)
@@ -352,11 +366,13 @@ private module Cached {
}
cached
predicate parameterNode(Node p, DataFlowCallable c, int pos) { isParameterNode(p, c, pos) }
predicate parameterNode(Node p, DataFlowCallable c, ParameterPosition pos) {
isParameterNode(p, c, pos)
}
cached
predicate argumentNode(Node n, DataFlowCall call, int pos) {
n.(ArgumentNode).argumentOf(call, pos)
predicate argumentNode(Node n, DataFlowCall call, ArgumentPosition pos) {
isArgumentNode(n, call, pos)
}
/**
@@ -374,12 +390,12 @@ private module Cached {
}
/**
* Holds if `p` is the `i`th parameter of a viable dispatch target of `call`.
* The instance parameter is considered to have index `-1`.
* Holds if `p` is the parameter of a viable dispatch target of `call`,
* and `p` has position `ppos`.
*/
pragma[nomagic]
private predicate viableParam(DataFlowCall call, int i, ParamNode p) {
p.isParameterOf(viableCallableExt(call), i)
private predicate viableParam(DataFlowCall call, ParameterPosition ppos, ParamNode p) {
p.isParameterOf(viableCallableExt(call), ppos)
}
/**
@@ -388,9 +404,9 @@ private module Cached {
*/
cached
predicate viableParamArg(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(int i |
viableParam(call, i, p) and
arg.argumentOf(call, i) and
exists(ParameterPosition ppos |
viableParam(call, ppos, p) and
argumentPositionMatch(call, arg, ppos) and
compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p))
)
}
@@ -862,7 +878,7 @@ private module Cached {
cached
newtype TReturnKindExt =
TValueReturn(ReturnKind kind) or
TParamUpdate(int pos) { exists(ParamNode p | p.isParameterOf(_, pos)) }
TParamUpdate(ParameterPosition pos) { exists(ParamNode p | p.isParameterOf(_, pos)) }
cached
newtype TBooleanOption =
@@ -1054,9 +1070,9 @@ class ParamNode extends Node {
/**
* Holds if this node is the parameter of callable `c` at the specified
* (zero-based) position.
* position.
*/
predicate isParameterOf(DataFlowCallable c, int i) { parameterNode(this, c, i) }
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { parameterNode(this, c, pos) }
}
/** A data-flow node that represents a call argument. */
@@ -1064,7 +1080,9 @@ class ArgNode extends Node {
ArgNode() { argumentNode(this, _, _) }
/** Holds if this argument occurs at the given position in the given call. */
final predicate argumentOf(DataFlowCall call, int pos) { argumentNode(this, call, pos) }
final predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
argumentNode(this, call, pos)
}
}
/**
@@ -1110,11 +1128,14 @@ class ValueReturnKind extends ReturnKindExt, TValueReturn {
}
class ParamUpdateReturnKind extends ReturnKindExt, TParamUpdate {
private int pos;
private ParameterPosition pos;
ParamUpdateReturnKind() { this = TParamUpdate(pos) }
int getPosition() { result = pos }
ParameterPosition getPosition() { result = pos }
pragma[nomagic]
ArgumentPosition getAMatchingArgumentPosition() { parameterMatch(pos, result) }
override string toString() { result = "param update " + pos }
}

View File

@@ -8,7 +8,14 @@ private import DataFlowImplConsistency
DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() }
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
predicate isParameterNode(ParameterNode p, DataFlowCallable c, int pos) { p.isParameterOf(c, pos) }
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) {
p.isParameterOf(c, pos)
}
/** Holds if `arg` is an `ArgumentNode` of `c` with position `pos`. */
predicate isArgumentNode(ArgumentNode arg, DataFlowCall c, ArgumentPosition pos) {
arg.argumentOf(c, pos)
}
/**
* A data flow node that occurs as the argument of a call and is passed as-is

View File

@@ -71,13 +71,30 @@ abstract class BufferWrite extends Expr {
*/
int getMaxData() { none() }
/**
* Gets an upper bound to the amount of data that's being written (if one
* can be found), specifying the reason for the estimation.
*/
int getMaxData(BufferWriteEstimationReason reason) {
reason instanceof NoSpecifiedEstimateReason and result = getMaxData()
}
/**
* Gets an upper bound to the amount of data that's being written (if one
* can be found), except that float to string conversions are assumed to be
* much smaller (8 bytes) than their true maximum length. This can be
* helpful in determining the cause of a buffer overflow issue.
*/
int getMaxDataLimited() { result = this.getMaxData() }
int getMaxDataLimited() { result = getMaxData() }
/**
* Gets an upper bound to the amount of data that's being written (if one
* can be found), specifying the reason for the estimation, except that
* float to string conversions are assumed to be much smaller (8 bytes)
* than their true maximum length. This can be helpful in determining the
* cause of a buffer overflow issue.
*/
int getMaxDataLimited(BufferWriteEstimationReason reason) { result = getMaxData(reason) }
/**
* Gets the size of a single character of the type this
@@ -135,10 +152,16 @@ class StrCopyBW extends BufferWriteCall {
result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
}
override int getMaxData() {
private int getMaxDataImpl(BufferWriteEstimationReason reason) {
// when result exists, it is an exact flow analysis
reason instanceof ValueFlowAnalysis and
result =
this.getArgument(this.getParamSrc()).(AnalysedString).getMaxLength() * this.getCharSize()
}
override int getMaxData(BufferWriteEstimationReason reason) { result = getMaxDataImpl(reason) }
override int getMaxData() { result = max(getMaxDataImpl(_)) }
}
/**
@@ -173,10 +196,16 @@ class StrCatBW extends BufferWriteCall {
result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
}
override int getMaxData() {
private int getMaxDataImpl(BufferWriteEstimationReason reason) {
// when result exists, it is an exact flow analysis
reason instanceof ValueFlowAnalysis and
result =
this.getArgument(this.getParamSrc()).(AnalysedString).getMaxLength() * this.getCharSize()
}
override int getMaxData(BufferWriteEstimationReason reason) { result = getMaxDataImpl(reason) }
override int getMaxData() { result = max(getMaxDataImpl(_)) }
}
/**
@@ -233,19 +262,29 @@ class SprintfBW extends BufferWriteCall {
override Expr getDest() { result = this.getArgument(f.getOutputParameterIndex(false)) }
override int getMaxData() {
private int getMaxDataImpl(BufferWriteEstimationReason reason) {
exists(FormatLiteral fl |
fl = this.(FormattingFunctionCall).getFormat() and
result = fl.getMaxConvertedLength() * this.getCharSize()
result = fl.getMaxConvertedLengthWithReason(reason) * this.getCharSize()
)
}
override int getMaxDataLimited() {
override int getMaxData(BufferWriteEstimationReason reason) { result = getMaxDataImpl(reason) }
override int getMaxData() { result = max(getMaxDataImpl(_)) }
private int getMaxDataLimitedImpl(BufferWriteEstimationReason reason) {
exists(FormatLiteral fl |
fl = this.(FormattingFunctionCall).getFormat() and
result = fl.getMaxConvertedLengthLimited() * this.getCharSize()
result = fl.getMaxConvertedLengthLimitedWithReason(reason) * this.getCharSize()
)
}
override int getMaxDataLimited(BufferWriteEstimationReason reason) {
result = getMaxDataLimitedImpl(reason)
}
override int getMaxDataLimited() { result = max(getMaxDataLimitedImpl(_)) }
}
/**
@@ -336,19 +375,29 @@ class SnprintfBW extends BufferWriteCall {
result = this.getArgument(this.getParamSize()).getValue().toInt() * this.getCharSize()
}
override int getMaxData() {
private int getMaxDataImpl(BufferWriteEstimationReason reason) {
exists(FormatLiteral fl |
fl = this.(FormattingFunctionCall).getFormat() and
result = fl.getMaxConvertedLength() * this.getCharSize()
result = fl.getMaxConvertedLengthWithReason(reason) * this.getCharSize()
)
}
override int getMaxDataLimited() {
override int getMaxData(BufferWriteEstimationReason reason) { result = getMaxDataImpl(reason) }
override int getMaxData() { result = max(getMaxDataImpl(_)) }
private int getMaxDataLimitedImpl(BufferWriteEstimationReason reason) {
exists(FormatLiteral fl |
fl = this.(FormattingFunctionCall).getFormat() and
result = fl.getMaxConvertedLengthLimited() * this.getCharSize()
result = fl.getMaxConvertedLengthLimitedWithReason(reason) * this.getCharSize()
)
}
override int getMaxDataLimited(BufferWriteEstimationReason reason) {
result = getMaxDataLimitedImpl(reason)
}
override int getMaxDataLimited() { result = max(getMaxDataLimitedImpl(_)) }
}
/**
@@ -436,7 +485,9 @@ class ScanfBW extends BufferWrite {
override Expr getDest() { result = this }
override int getMaxData() {
private int getMaxDataImpl(BufferWriteEstimationReason reason) {
// when this returns, it is based on exact flow analysis
reason instanceof ValueFlowAnalysis and
exists(ScanfFunctionCall fc, ScanfFormatLiteral fl, int arg |
this = fc.getArgument(arg) and
fl = fc.getFormat() and
@@ -444,6 +495,10 @@ class ScanfBW extends BufferWrite {
)
}
override int getMaxData(BufferWriteEstimationReason reason) { result = getMaxDataImpl(reason) }
override int getMaxData() { result = max(getMaxDataImpl(_)) }
override string getBWDesc() {
exists(FunctionCall fc |
this = fc.getArgument(_) and
@@ -474,8 +529,14 @@ class RealpathBW extends BufferWriteCall {
override Expr getASource() { result = this.getArgument(0) }
override int getMaxData() {
private int getMaxDataImpl(BufferWriteEstimationReason reason) {
// although there may be some unknown invariants guaranteeing that a real path is shorter than PATH_MAX, we can consider providing less than PATH_MAX a problem with high precision
reason instanceof ValueFlowAnalysis and
result = path_max() and
this = this // Suppress a compiler warning
}
override int getMaxData(BufferWriteEstimationReason reason) { result = getMaxDataImpl(reason) }
override int getMaxData() { result = max(getMaxDataImpl(_)) }
}

5
cpp/ql/src/CHANGELOG.md Normal file
View File

@@ -0,0 +1,5 @@
## 0.0.4
### New Queries
* A new query `cpp/non-https-url` has been added for C/C++. The query flags uses of `http` URLs that might be better replaced with `https`.

View File

@@ -85,7 +85,8 @@ private predicate cancelingSubExprs(ComparisonOperation cmp, VariableAccess a1,
exists(Variable v |
exists(float m | m < 0 and cmpLinearSubVariable(cmp, v, a1, m)) and
exists(float m | m > 0 and cmpLinearSubVariable(cmp, v, a2, m))
)
) and
not any(ClassTemplateInstantiation inst).getATemplateArgument() = cmp.getParent*()
}
from ComparisonOperation cmp, VariableAccess a1, VariableAccess a2

View File

@@ -29,7 +29,9 @@ predicate pointlessSelfComparison(ComparisonOperation cmp) {
not exists(lhs.getQualifier()) and // Avoid structure fields
not exists(rhs.getQualifier()) and // Avoid structure fields
not convertedExprMightOverflow(lhs) and
not convertedExprMightOverflow(rhs)
not convertedExprMightOverflow(rhs) and
// Don't warn if the comparison is part of a template argument.
not any(ClassTemplateInstantiation inst).getATemplateArgument() = cmp.getParent*()
)
}

View File

@@ -21,14 +21,15 @@ import semmle.code.cpp.commons.Alloc
* See CWE-120/UnboundedWrite.ql for a summary of CWE-120 alert cases.
*/
from BufferWrite bw, Expr dest, int destSize
from BufferWrite bw, Expr dest, int destSize, int estimated
where
not bw.hasExplicitLimit() and // has no explicit size limit
dest = bw.getDest() and
destSize = getBufferSize(dest, _) and
estimated = bw.getMaxDataLimited(_) and
// we can deduce that too much data may be copied (even without
// long '%f' conversions)
bw.getMaxDataLimited() > destSize
estimated > destSize
select bw,
"This '" + bw.getBWDesc() + "' operation requires " + bw.getMaxData() +
"This '" + bw.getBWDesc() + "' operation requires " + estimated +
" bytes but the destination is only " + destSize + " bytes."

View File

@@ -21,14 +21,15 @@ import semmle.code.cpp.security.BufferWrite
* See CWE-120/UnboundedWrite.ql for a summary of CWE-120 alert cases.
*/
from BufferWrite bw, int destSize
from BufferWrite bw, int destSize, int estimated, BufferWriteEstimationReason reason
where
not bw.hasExplicitLimit() and
// has no explicit size limit
destSize = getBufferSize(bw.getDest(), _) and
bw.getMaxData() > destSize and
estimated = bw.getMaxData(reason) and
estimated > destSize and
// and we can deduce that too much data may be copied
bw.getMaxDataLimited() <= destSize // but it would fit without long '%f' conversions
bw.getMaxDataLimited(reason) <= destSize // but it would fit without long '%f' conversions
select bw,
"This '" + bw.getBWDesc() + "' operation may require " + bw.getMaxData() +
"This '" + bw.getBWDesc() + "' operation may require " + estimated +
" bytes because of float conversions, but the target is only " + destSize + " bytes."

View File

@@ -44,7 +44,7 @@ import TaintedWithPath
predicate isUnboundedWrite(BufferWrite bw) {
not bw.hasExplicitLimit() and // has no explicit size limit
not exists(bw.getMaxData()) // and we can't deduce an upper bound to the amount copied
not exists(bw.getMaxData(_)) // and we can't deduce an upper bound to the amount copied
}
/*

View File

@@ -28,6 +28,11 @@ class PrivateHostName extends string {
}
}
pragma[nomagic]
predicate privateHostNameFlowsToExpr(Expr e) {
TaintTracking::localExprTaint(any(StringLiteral p | p.getValue() instanceof PrivateHostName), e)
}
/**
* A string containing an HTTP URL not in a private domain.
*/
@@ -38,11 +43,9 @@ class HttpStringLiteral extends StringLiteral {
or
exists(string tail |
tail = s.regexpCapture("http://(.*)", 1) and not tail instanceof PrivateHostName
) and
not TaintTracking::localExprTaint(any(StringLiteral p |
p.getValue() instanceof PrivateHostName
), this.getParent*())
)
)
) and
not privateHostNameFlowsToExpr(this.getParent*())
}
}

View File

@@ -0,0 +1,5 @@
## 0.0.4
### New Queries
* A new query `cpp/non-https-url` has been added for C/C++. The query flags uses of `http` URLs that might be better replaced with `https`.

View File

@@ -0,0 +1,2 @@
---
lastReleaseVersion: 0.0.4

View File

@@ -1,5 +1,6 @@
name: codeql/cpp-queries
version: 0.0.2
version: 0.0.5-dev
groups: cpp
dependencies:
codeql/cpp-all: "*"
codeql/suite-helpers: "*"

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-tests
version: 0.0.2
groups: [cpp, test]
dependencies:
codeql/cpp-all: "*"
codeql/cpp-queries: "*"

View File

@@ -20,3 +20,22 @@ bool compareValues() {
bool callCompareValues() {
return compareValues<C1, C2> || compareValues<C1, C1>();
}
template <bool C, typename T = void>
struct enable_if {};
template <typename T>
struct enable_if<true, T> { typedef T type; };
template<typename T1, typename T2>
typename enable_if<T1::value <= T2::value, bool>::type constant_comparison() {
return true;
}
struct Value0 {
const static int value = 0;
};
void instantiation_with_pointless_comparison() {
constant_comparison<Value0, Value0>(); // GOOD
}

View File

@@ -1,6 +1,6 @@
# This directory has its own qlpack for reasons detailed in commit 2550788598010fa2117274607c9d58f64f997f34
name: codeql/cpp-tests-cwe-190-tainted
version: 0.0.2
groups: [cpp, test]
dependencies:
codeql/cpp-all: "*"
codeql/cpp-queries: "*"

View File

@@ -0,0 +1 @@
## 0.0.4

View File

@@ -0,0 +1 @@
## 0.0.4

View File

@@ -0,0 +1,2 @@
---
lastReleaseVersion: 0.0.4

View File

@@ -1,4 +1,5 @@
name: codeql/cpp-upgrades
groups: cpp
upgrades: .
version: 0.0.2
version: 0.0.5-dev
library: true

View File

@@ -1,25 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.IO.FileSystem" Version="4.3.0" />
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Autobuild.CSharp\Semmle.Autobuild.CSharp.csproj" />
<ProjectReference Include="..\Semmle.Autobuild.Shared\Semmle.Autobuild.Shared.csproj" />
</ItemGroup>
</Project>
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.IO.FileSystem" Version="4.3.0"/>
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0"/>
<PackageReference Include="xunit" Version="2.4.1"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Autobuild.CSharp\Semmle.Autobuild.CSharp.csproj"/>
<ProjectReference Include="..\Semmle.Autobuild.Shared\Semmle.Autobuild.Shared.csproj"/>
</ItemGroup>
</Project>

View File

@@ -1,30 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Semmle.Autobuild.CSharp</AssemblyName>
<RootNamespace>Semmle.Autobuild.CSharp</RootNamespace>
<ApplicationIcon />
<OutputType>Exe</OutputType>
<StartupObject />
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="16.9.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\extractor\Semmle.Util\Semmle.Util.csproj" />
<ProjectReference Include="..\..\extractor\Semmle.Extraction.CSharp\Semmle.Extraction.CSharp.csproj" />
<ProjectReference Include="..\Semmle.Autobuild.Shared\Semmle.Autobuild.Shared.csproj" />
</ItemGroup>
</Project>
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Semmle.Autobuild.CSharp</AssemblyName>
<RootNamespace>Semmle.Autobuild.CSharp</RootNamespace>
<ApplicationIcon/>
<OutputType>Exe</OutputType>
<StartupObject/>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Folder Include="Properties\"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="16.11.0"/>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\extractor\Semmle.Util\Semmle.Util.csproj"/>
<ProjectReference Include="..\..\extractor\Semmle.Extraction.CSharp\Semmle.Extraction.CSharp.csproj"/>
<ProjectReference Include="..\Semmle.Autobuild.Shared\Semmle.Autobuild.Shared.csproj"/>
</ItemGroup>
</Project>

View File

@@ -1,24 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Semmle.Autobuild.Shared</AssemblyName>
<RootNamespace>Semmle.Autobuild.Shared</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="16.9.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\extractor\Semmle.Util\Semmle.Util.csproj" />
</ItemGroup>
</Project>
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Semmle.Autobuild.Shared</AssemblyName>
<RootNamespace>Semmle.Autobuild.Shared</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Folder Include="Properties\"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="16.11.0"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\extractor\Semmle.Util\Semmle.Util.csproj"/>
</ItemGroup>
</Project>

View File

@@ -1,6 +1,7 @@
package,sink,source,summary,sink:code,sink:html,sink:remote,sink:sql,sink:xss,source:local,summary:taint
Dapper,55,,,,,,55,,,
Microsoft.ApplicationBlocks.Data,28,,,,,,28,,,
MySql.Data.MySqlClient,48,,,,,,48,,,
ServiceStack,194,,7,27,,75,92,,,7
System,28,3,25,,4,,23,1,3,25
package,sink,source,summary,sink:code,sink:html,sink:remote,sink:sql,sink:xss,source:local,summary:taint,summary:value
Dapper,55,,,,,,55,,,,
Microsoft.ApplicationBlocks.Data,28,,,,,,28,,,,
MySql.Data.MySqlClient,48,,,,,,48,,,,
Newtonsoft.Json,,,73,,,,,,,73,
ServiceStack,194,,7,27,,75,92,,,7,
System,28,3,1221,,4,,23,1,3,611,610
1 package sink source summary sink:code sink:html sink:remote sink:sql sink:xss source:local summary:taint summary:value
2 Dapper 55 55
3 Microsoft.ApplicationBlocks.Data 28 28
4 MySql.Data.MySqlClient 48 48
5 ServiceStack Newtonsoft.Json 194 7 73 27 75 92 7 73
6 System ServiceStack 28 194 3 25 7 27 4 75 23 92 1 3 25 7
7 System 28 3 1221 4 23 1 3 611 610

View File

@@ -8,7 +8,7 @@ C# framework & library support
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting`
`ServiceStack <https://servicestack.net/>`_,"``ServiceStack.*``, ``ServiceStack``",,7,194,
System,"``System.*``, ``System``",3,25,28,5
Others,"``Dapper``, ``Microsoft.ApplicationBlocks.Data``, ``MySql.Data.MySqlClient``",,,131,
Totals,,3,32,353,5
System,"``System.*``, ``System``",3,1221,28,5
Others,"``Dapper``, ``Microsoft.ApplicationBlocks.Data``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``",,73,131,
Totals,,3,1301,353,5

View File

@@ -26,7 +26,9 @@
<ItemGroup>
<PackageReference Include="Microsoft.DiaSymReader" Version="1.3.0" />
<PackageReference Include="Microsoft.DiaSymReader.Native" Version="1.7.0" />
<PackageReference Include="Microsoft.DiaSymReader.PortablePdb" Version="1.5.0" />
<PackageReference Include="Microsoft.DiaSymReader.PortablePdb" Version="1.6.0"><IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
</Project>

View File

@@ -1,33 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Semmle.Extraction.CSharp.Standalone</AssemblyName>
<RootNamespace>Semmle.Extraction.CSharp.Standalone</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningsAsErrors />
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Extraction.CSharp\Semmle.Extraction.CSharp.csproj" />
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="16.9.0" />
<PackageReference Include="Microsoft.Win32.Primitives" Version="4.3.0" />
<PackageReference Include="System.Net.Primitives" Version="4.3.1" />
<PackageReference Include="System.Security.Principal" Version="4.3.0" />
<PackageReference Include="System.Threading.ThreadPool" Version="4.3.0" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Semmle.Extraction.CSharp.Standalone</AssemblyName>
<RootNamespace>Semmle.Extraction.CSharp.Standalone</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningsAsErrors/>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Extraction.CSharp\Semmle.Extraction.CSharp.csproj"/>
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj"/>
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="16.11.0"/>
<PackageReference Include="Microsoft.Win32.Primitives" Version="4.3.0"/>
<PackageReference Include="System.Net.Primitives" Version="4.3.1"/>
<PackageReference Include="System.Security.Principal" Version="4.3.0"/>
<PackageReference Include="System.Threading.ThreadPool" Version="4.3.0"/>
</ItemGroup>
</Project>

View File

@@ -18,6 +18,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
private void VisitParameter(ParameterSyntax p)
{
var symbol = Context.GetModel(p).GetDeclaredSymbol(p)!;
Context.CacheLambdaParameterSymbol(symbol, p);
Parameter.Create(Context, symbol, this);
}

View File

@@ -55,11 +55,17 @@ namespace Semmle.Extraction.CSharp.Entities
}
}
public static Parameter Create(Context cx, IParameterSymbol param, IEntity parent, Parameter? original = null) =>
ParameterFactory.Instance.CreateEntity(cx, param, (param, parent, original));
public static Parameter Create(Context cx, IParameterSymbol param, IEntity parent, Parameter? original = null)
{
var cachedSymbol = cx.GetPossiblyCachedParameterSymbol(param);
return ParameterFactory.Instance.CreateEntity(cx, cachedSymbol, (cachedSymbol, parent, original));
}
public static Parameter Create(Context cx, IParameterSymbol param) =>
ParameterFactory.Instance.CreateEntity(cx, param, (param, null, null));
public static Parameter Create(Context cx, IParameterSymbol param)
{
var cachedSymbol = cx.GetPossiblyCachedParameterSymbol(param);
return ParameterFactory.Instance.CreateEntity(cx, cachedSymbol, (cachedSymbol, null, null));
}
public override void WriteId(EscapingTextWriter trapFile)
{

View File

@@ -1,7 +1,6 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Semmle.Extraction.CSharp.Populators;
using Semmle.Extraction.Entities;
using System;
using System.Collections.Generic;
using System.IO;
@@ -36,6 +35,7 @@ namespace Semmle.Extraction.CSharp.Entities
{
if (Symbol.TypeKind == TypeKind.Error)
{
UnknownType.Create(Context); // make sure this exists so we can use it in `TypeRef::getReferencedType`
Context.Extractor.MissingType(Symbol.ToString()!, Context.FromSource);
return;
}
@@ -48,7 +48,7 @@ namespace Semmle.Extraction.CSharp.Entities
if (Symbol.IsBoundNullable())
{
// An instance of Nullable<T>
trapFile.nullable_underlying_type(this, Create(Context, Symbol.TypeArguments[0]).TypeRef);
trapFile.nullable_underlying_type(this, TypeArguments[0].TypeRef);
}
else if (Symbol.IsReallyUnbound())
{
@@ -67,7 +67,7 @@ namespace Semmle.Extraction.CSharp.Entities
: Type.Create(Context, Symbol.ConstructedFrom);
trapFile.constructed_generic(this, unbound.TypeRef);
for (var i = 0; i < Symbol.TypeArguments.Length; ++i)
for (var i = 0; i < TypeArguments.Length; ++i)
{
trapFile.type_arguments(TypeArguments[i].TypeRef, i, this);
}

View File

@@ -1,6 +1,5 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Semmle.Util;
using System;
using System.Collections.Generic;
using System.IO;
@@ -24,9 +23,9 @@ namespace Semmle.Extraction.CSharp.Entities
symbol.ContainingType is not null && ConstructedOrParentIsConstructed(symbol.ContainingType);
}
private static Kinds.TypeKind GetClassType(Context cx, ITypeSymbol t, bool constructUnderlyingTupleType)
public Kinds.TypeKind GetTypeKind(Context cx, bool constructUnderlyingTupleType)
{
switch (t.SpecialType)
switch (Symbol.SpecialType)
{
case SpecialType.System_Int32: return Kinds.TypeKind.INT;
case SpecialType.System_UInt32: return Kinds.TypeKind.UINT;
@@ -44,14 +43,14 @@ namespace Semmle.Extraction.CSharp.Entities
case SpecialType.System_Single: return Kinds.TypeKind.FLOAT;
case SpecialType.System_IntPtr: return Kinds.TypeKind.INT_PTR;
default:
if (t.IsBoundNullable())
if (Symbol.IsBoundNullable())
return Kinds.TypeKind.NULLABLE;
switch (t.TypeKind)
switch (Symbol.TypeKind)
{
case TypeKind.Class: return Kinds.TypeKind.CLASS;
case TypeKind.Struct:
return ((INamedTypeSymbol)t).IsTupleType && !constructUnderlyingTupleType
return ((INamedTypeSymbol)Symbol).IsTupleType && !constructUnderlyingTupleType
? Kinds.TypeKind.TUPLE
: Kinds.TypeKind.STRUCT;
case TypeKind.Interface: return Kinds.TypeKind.INTERFACE;
@@ -62,7 +61,7 @@ namespace Semmle.Extraction.CSharp.Entities
case TypeKind.FunctionPointer: return Kinds.TypeKind.FUNCTION_POINTER;
case TypeKind.Error: return Kinds.TypeKind.UNKNOWN;
default:
cx.ModelError(t, $"Unhandled type kind '{t.TypeKind}'");
cx.ModelError(Symbol, $"Unhandled type kind '{Symbol.TypeKind}'");
return Kinds.TypeKind.UNKNOWN;
}
}
@@ -76,7 +75,7 @@ namespace Semmle.Extraction.CSharp.Entities
trapFile.Write("types(");
trapFile.WriteColumn(this);
trapFile.Write(',');
trapFile.WriteColumn((int)GetClassType(Context, Symbol, constructUnderlyingTupleType));
trapFile.WriteColumn((int)GetTypeKind(Context, constructUnderlyingTupleType));
trapFile.Write(",\"");
Symbol.BuildDisplayName(Context, trapFile, constructUnderlyingTupleType);
trapFile.WriteLine("\")");

View File

@@ -0,0 +1,39 @@
using System.IO;
using Microsoft.CodeAnalysis;
namespace Semmle.Extraction.CSharp.Entities
{
internal class UnknownType : Type
{
private UnknownType(Context cx)
: base(cx, null) { }
public override void Populate(TextWriter trapFile)
{
trapFile.types(this, Kinds.TypeKind.UNKNOWN, "<unknown type>");
}
public override void WriteId(EscapingTextWriter trapFile)
{
trapFile.Write("<unknown>;type");
}
public override bool NeedsPopulation => true;
public override int GetHashCode() => 98744554;
public override bool Equals(object? obj)
{
return obj is not null && obj.GetType() == typeof(UnknownType);
}
public static Type Create(Context cx) => UnknownTypeFactory.Instance.CreateEntity(cx, typeof(UnknownType), null);
private class UnknownTypeFactory : CachedEntityFactory<ITypeSymbol?, UnknownType>
{
public static UnknownTypeFactory Instance { get; } = new UnknownTypeFactory();
public override UnknownType Create(Context cx, ITypeSymbol? init) => new UnknownType(cx);
}
}
}

View File

@@ -18,18 +18,56 @@ namespace Semmle.Extraction.CSharp
/// </summary>
public SemanticModel GetModel(SyntaxNode node)
{
// todo: when this context belongs to a SourceScope, the syntax tree can be retrieved from the scope, and
// the node parameter could be removed. Is there any case when we pass in a node that's not from the current
// tree?
if (cachedModel is null || node.SyntaxTree != cachedModel.SyntaxTree)
if (node.SyntaxTree == SourceTree)
{
cachedModel = Compilation.GetSemanticModel(node.SyntaxTree);
if (cachedModelForTree is null)
{
cachedModelForTree = Compilation.GetSemanticModel(node.SyntaxTree);
}
return cachedModelForTree;
}
return cachedModel;
if (cachedModelForOtherTrees is null || node.SyntaxTree != cachedModelForOtherTrees.SyntaxTree)
{
cachedModelForOtherTrees = Compilation.GetSemanticModel(node.SyntaxTree);
}
return cachedModelForOtherTrees;
}
private SemanticModel? cachedModel;
private SemanticModel? cachedModelForTree;
private SemanticModel? cachedModelForOtherTrees;
// The below is a workaround to the bug reported in https://github.com/dotnet/roslyn/issues/58226
// Lambda parameters that are equal according to `SymbolEqualityComparer.Default`, might have different
// hash-codes, and as a result might not be found in `symbolEntityCache` by hash-code lookup.
internal IParameterSymbol GetPossiblyCachedParameterSymbol(IParameterSymbol param)
{
if ((param.ContainingSymbol as IMethodSymbol)?.MethodKind != MethodKind.AnonymousFunction)
{
return param;
}
foreach (var sr in param.DeclaringSyntaxReferences)
{
var syntax = sr.GetSyntax();
if (lambdaParameterCache.TryGetValue(syntax, out var cached) &&
SymbolEqualityComparer.Default.Equals(param, cached))
{
return cached;
}
}
return param;
}
internal void CacheLambdaParameterSymbol(IParameterSymbol param, SyntaxNode syntax)
{
lambdaParameterCache[syntax] = param;
}
private readonly Dictionary<SyntaxNode, IParameterSymbol> lambdaParameterCache = new Dictionary<SyntaxNode, IParameterSymbol>();
/// <summary>
/// The current compilation unit.

View File

@@ -1,29 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Semmle.Extraction.CSharp</AssemblyName>
<RootNamespace>Semmle.Extraction.CSharp</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Extraction.CIL\Semmle.Extraction.CIL.csproj" />
<ProjectReference Include="..\Semmle.Extraction\Semmle.Extraction.csproj" />
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.9.0" />
<PackageReference Include="Microsoft.Build" Version="16.9.0" />
</ItemGroup>
</Project>
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Semmle.Extraction.CSharp</AssemblyName>
<RootNamespace>Semmle.Extraction.CSharp</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Extraction.CIL\Semmle.Extraction.CIL.csproj"/>
<ProjectReference Include="..\Semmle.Extraction\Semmle.Extraction.csproj"/>
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj"/>
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1"/>
<PackageReference Include="Microsoft.Build" Version="16.11.0"/>
</ItemGroup>
</Project>

View File

@@ -1,28 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.IO.FileSystem" Version="4.3.0" />
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Extraction.CSharp.Standalone\Semmle.Extraction.CSharp.Standalone.csproj" />
<ProjectReference Include="..\Semmle.Extraction.CSharp\Semmle.Extraction.CSharp.csproj" />
<ProjectReference Include="..\Semmle.Extraction\Semmle.Extraction.csproj" />
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj" />
</ItemGroup>
</Project>
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.IO.FileSystem" Version="4.3.0"/>
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0"/>
<PackageReference Include="xunit" Version="2.4.1"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Extraction.CSharp.Standalone\Semmle.Extraction.CSharp.Standalone.csproj"/>
<ProjectReference Include="..\Semmle.Extraction.CSharp\Semmle.Extraction.CSharp.csproj"/>
<ProjectReference Include="..\Semmle.Extraction\Semmle.Extraction.csproj"/>
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj"/>
</ItemGroup>
</Project>

View File

@@ -1,29 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Semmle.Extraction</AssemblyName>
<RootNamespace>Semmle.Extraction</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<CodeAnalysisRuleSet>Semmle.Extraction.ruleset</CodeAnalysisRuleSet>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>TRACE;DEBUG;DEBUG_LABELS</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.9.0" />
<PackageReference Include="GitInfo" Version="2.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Semmle.Extraction</AssemblyName>
<RootNamespace>Semmle.Extraction</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<CodeAnalysisRuleSet>Semmle.Extraction.ruleset</CodeAnalysisRuleSet>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>TRACE;DEBUG;DEBUG_LABELS</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis" Version="4.0.1"/>
<PackageReference Include="GitInfo" Version="2.2.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj"/>
</ItemGroup>
</Project>

View File

@@ -1,23 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj" />
</ItemGroup>
</Project>
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="xunit" Version="2.4.1"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj"/>
</ItemGroup>
</Project>

View File

@@ -0,0 +1 @@
## 0.0.4

View File

@@ -0,0 +1 @@
## 0.0.4

View File

@@ -0,0 +1,2 @@
---
lastReleaseVersion: 0.0.4

View File

@@ -2,40 +2,5 @@
* The default C# QL library.
*/
import Customizations
import semmle.code.csharp.Attribute
import semmle.code.csharp.Callable
import semmle.code.csharp.Comments
import semmle.code.csharp.Element
import semmle.code.csharp.Event
import semmle.code.csharp.File
import semmle.code.csharp.Generics
import semmle.code.csharp.Location
import semmle.code.csharp.Member
import semmle.code.csharp.Namespace
import semmle.code.csharp.AnnotatedType
import semmle.code.csharp.Property
import semmle.code.csharp.Stmt
import semmle.code.csharp.Type
import semmle.code.csharp.Using
import semmle.code.csharp.Variable
import semmle.code.csharp.XML
import semmle.code.csharp.Preprocessor
import semmle.code.csharp.exprs.Access
import semmle.code.csharp.exprs.ArithmeticOperation
import semmle.code.csharp.exprs.Assignment
import semmle.code.csharp.exprs.BitwiseOperation
import semmle.code.csharp.exprs.Call
import semmle.code.csharp.exprs.ComparisonOperation
import semmle.code.csharp.exprs.Creation
import semmle.code.csharp.exprs.Dynamic
import semmle.code.csharp.exprs.Expr
import semmle.code.csharp.exprs.Literal
import semmle.code.csharp.exprs.LogicalOperation
import semmle.code.csharp.controlflow.ControlFlowGraph
import semmle.code.csharp.dataflow.DataFlow
import semmle.code.csharp.dataflow.TaintTracking
import semmle.code.csharp.dataflow.SSA
/** Whether the source was extracted without a build command. */
predicate extractionIsStandalone() { exists(SourceFile f | f.extractedStandalone()) }
// Do not add other imports here; add to `semmle.code.csharp.internal.csharp` instead
import semmle.code.csharp.internal.csharp

View File

@@ -1,7 +1,8 @@
name: codeql/csharp-all
version: 0.0.2
version: 0.0.5-dev
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp
library: true
dependencies:
codeql/csharp-upgrades: 0.0.2
codeql/csharp-upgrades: ^0.0.3

View File

@@ -25,7 +25,7 @@ private module Cached {
cached
predicate alwaysThrowsException(Method m, Type t) {
alwaysThrowsMethod(m) and
forex(Throw ex | ex = m.getImplementation().getAnInstruction() | t = ex.getExpr().getType())
forex(Throw ex | ex = m.getImplementation().getAnInstruction() | t = ex.getExceptionType())
}
}

View File

@@ -612,7 +612,7 @@ class ExprMissingType extends InstructionViolation {
not instruction instanceof Opcodes::Ldvirtftn and
not instruction instanceof Opcodes::Arglist and
not instruction instanceof Opcodes::Refanytype and
instruction.getPushCount() = 1 and
instruction.getPushCount() >= 1 and
count(instruction.getType()) != 1
}

View File

@@ -56,6 +56,32 @@ class ControlFlowNode extends @cil_controlflow_node {
)
}
/**
* Gets the type of the `i`th operand. Unlike `getOperand(i).getType()`, this
* predicate takes into account when there are multiple possible operands with
* different types.
*/
Type getOperandType(int i) {
strictcount(this.getOperand(i)) = 1 and
result = this.getOperand(i).getType()
or
strictcount(this.getOperand(i)) = 2 and
exists(ControlFlowNode op1, ControlFlowNode op2, Type t2 |
op1 = this.getOperand(i) and
op2 = this.getOperand(i) and
op1 != op2 and
result = op1.getType() and
t2 = op2.getType()
|
result = t2
or
result.(PrimitiveType).getUnderlyingType().getConversionIndex() >
t2.(PrimitiveType).getUnderlyingType().getConversionIndex()
or
op2 instanceof NullLiteral
)
}
/** Gets an operand of this instruction, if any. */
ControlFlowNode getAnOperand() { result = this.getOperand(_) }
@@ -102,7 +128,12 @@ class ControlFlowNode extends @cil_controlflow_node {
/** Gets the method containing this control flow node. */
MethodImplementation getImplementation() { none() }
/** Gets the type of the item pushed onto the stack, if any. */
/**
* Gets the type of the item pushed onto the stack, if any.
*
* If called via `ControlFlowNode::getOperand(i).getType()`, consider using
* `ControlFlowNode::getOperandType(i)` instead.
*/
cached
Type getType() { none() }

View File

@@ -73,8 +73,8 @@ class ComparisonOperation extends BinaryExpr, @cil_comparison_operation {
class BinaryArithmeticExpr extends BinaryExpr, @cil_binary_arithmetic_operation {
override Type getType() {
exists(Type t0, Type t1 |
t0 = this.getOperand(0).getType().getUnderlyingType() and
t1 = this.getOperand(1).getType().getUnderlyingType()
t0 = this.getOperandType(0).getUnderlyingType() and
t1 = this.getOperandType(1).getUnderlyingType()
|
t0 = t1 and result = t0
or
@@ -242,6 +242,9 @@ class Return extends Instruction, @cil_ret {
class Throw extends Instruction, DotNet::Throw, @cil_throw_any {
override Expr getExpr() { result = this.getOperand(0) }
/** Gets the type of the exception being thrown. */
Type getExceptionType() { result = this.getOperandType(0) }
override predicate canFlowNext() { none() }
}

View File

@@ -199,9 +199,9 @@ module Opcodes {
override string getOpcodeName() { result = "neg" }
override NumericType getType() {
result = this.getOperand().getType()
result = this.getOperandType(0)
or
this.getOperand().getType() instanceof Enum and result instanceof IntType
this.getOperandType(0) instanceof Enum and result instanceof IntType
}
}
@@ -260,7 +260,7 @@ module Opcodes {
override int getPushCount() { result = 2 } // This is the only instruction that pushes 2 items
override Type getType() { result = this.getOperand(0).getType() }
override Type getType() { result = this.getOperandType(0) }
}
/** A `ret` instruction. */
@@ -887,7 +887,7 @@ module Opcodes {
class Ldelem_ref extends ReadArrayElement, @cil_ldelem_ref {
override string getOpcodeName() { result = "ldelem.ref" }
override Type getType() { result = this.getArray().getType() }
override Type getType() { result = this.getOperandType(1) }
}
/** An `ldelema` instruction. */

View File

@@ -205,7 +205,7 @@ private class RefArg extends AssignableAccess {
*/
predicate isAnalyzable(Parameter p) {
exists(Callable callable | callable = this.getUnboundDeclarationTarget(p) |
not callable.(Virtualizable).isOverridableOrImplementable() and
not callable.(Overridable).isOverridableOrImplementable() and
callable.hasBody()
)
}

View File

@@ -4,7 +4,7 @@
* Provides logic for determining interface member implementations.
*
* Do not use the predicates in this library directly; use the methods
* of the class `Virtualizable` instead.
* of the class `Overridable` instead.
*/
import csharp
@@ -35,7 +35,26 @@ private import Conversion
* `implements(A.M, I.M, B)` and `implements(C.M, I.M, C)`.
*/
cached
predicate implements(Virtualizable m1, Virtualizable m2, ValueOrRefType t) {
predicate implements(Overridable m1, Overridable m2, ValueOrRefType t) {
implementsVirtualizable(m1, m2, t)
or
exists(DeclarationWithAccessors d1, DeclarationWithAccessors d2, int kind |
implementsVirtualizable(d1, d2, t) and
hasAccessor(d1, m1, pragma[only_bind_into](kind)) and
hasAccessor(d2, m2, pragma[only_bind_into](kind))
)
}
pragma[noinline]
private predicate hasAccessor(DeclarationWithAccessors d, Accessor a, int kind) {
a = d.getAnAccessor() and
(
accessors(a, kind, _, _, _) or
event_accessors(a, kind, _, _, _)
)
}
private predicate implementsVirtualizable(Virtualizable m1, Virtualizable m2, ValueOrRefType t) {
exists(Interface i |
i = m2.getDeclaringType() and
t.getABaseInterface+() = i and

View File

@@ -180,29 +180,15 @@ class Member extends DotNet::Member, Modifiable, @member {
override predicate isStatic() { Modifiable.super.isStatic() }
}
private class TOverridable = @virtualizable or @callable_accessor;
/**
* A member where the `virtual` modifier is valid. That is, a method,
* a property, an indexer, or an event.
* A declaration that can be overridden or implemented. That is, a method,
* a property, an indexer, an event, or an accessor.
*
* Equivalently, these are the members that can be defined in an interface.
* Unlike `Virtualizable`, this class includes accessors.
*/
class Virtualizable extends Member, @virtualizable {
/** Holds if this member has the modifier `override`. */
predicate isOverride() { this.hasModifier("override") }
/** Holds if this member is `virtual`. */
predicate isVirtual() { this.hasModifier("virtual") }
override predicate isPublic() {
Member.super.isPublic() or
this.implementsExplicitInterface()
}
override predicate isPrivate() {
super.isPrivate() and
not this.implementsExplicitInterface()
}
class Overridable extends Declaration, TOverridable {
/**
* Gets any interface this member explicitly implements; this only applies
* to members that can be declared on an interface, i.e. methods, properties,
@@ -216,19 +202,10 @@ class Virtualizable extends Member, @virtualizable {
predicate implementsExplicitInterface() { exists(this.getExplicitlyImplementedInterface()) }
/** Holds if this member can be overridden or implemented. */
predicate isOverridableOrImplementable() {
not this.isSealed() and
not this.getDeclaringType().isSealed() and
(
this.isVirtual() or
this.isOverride() or
this.isAbstract() or
this.getDeclaringType() instanceof Interface
)
}
predicate isOverridableOrImplementable() { none() }
/** Gets the member that is immediately overridden by this member, if any. */
Virtualizable getOverridee() {
Overridable getOverridee() {
overrides(this, result)
or
// For accessors (which are `Callable`s), the extractor generates entries
@@ -242,7 +219,7 @@ class Virtualizable extends Member, @virtualizable {
}
/** Gets a member that immediately overrides this member, if any. */
Virtualizable getAnOverrider() { this = result.getOverridee() }
Overridable getAnOverrider() { this = result.getOverridee() }
/** Holds if this member is overridden by some other member. */
predicate isOverridden() { exists(this.getAnOverrider()) }
@@ -273,10 +250,10 @@ class Virtualizable extends Member, @virtualizable {
* `A.M.getImplementee(B) = I.M` and
* `C.M.getImplementee(C) = I.M`.
*/
Virtualizable getImplementee(ValueOrRefType t) { implements(this, result, t) }
Overridable getImplementee(ValueOrRefType t) { implements(this, result, t) }
/** Gets the interface member that is immediately implemented by this member, if any. */
Virtualizable getImplementee() { result = this.getImplementee(_) }
Overridable getImplementee() { result = this.getImplementee(_) }
/**
* Gets a member that immediately implements this interface member, if any.
@@ -301,10 +278,10 @@ class Virtualizable extends Member, @virtualizable {
* `I.M.getAnImplementor(B) = A.M` and
* `I.M.getAnImplementor(C) = C.M`.
*/
Virtualizable getAnImplementor(ValueOrRefType t) { this = result.getImplementee(t) }
Overridable getAnImplementor(ValueOrRefType t) { this = result.getImplementee(t) }
/** Gets a member that immediately implements this interface member, if any. */
Virtualizable getAnImplementor() { this = result.getImplementee() }
Overridable getAnImplementor() { this = result.getImplementee() }
/**
* Gets an interface member that is (transitively) implemented by this
@@ -334,8 +311,8 @@ class Virtualizable extends Member, @virtualizable {
* - If this member is `D.M` then `I.M = getAnUltimateImplementee()`.
*/
pragma[nomagic]
Virtualizable getAnUltimateImplementee() {
exists(Virtualizable implementation, ValueOrRefType implementationType |
Overridable getAnUltimateImplementee() {
exists(Overridable implementation, ValueOrRefType implementationType |
implements(implementation, result, implementationType)
|
this = implementation
@@ -354,7 +331,7 @@ class Virtualizable extends Member, @virtualizable {
* Note that this is generally *not* equivalent with
* `getImplementor().getAnOverrider*()` (see `getImplementee`).
*/
Virtualizable getAnUltimateImplementor() { this = result.getAnUltimateImplementee() }
Overridable getAnUltimateImplementor() { this = result.getAnUltimateImplementee() }
/** Holds if this interface member is implemented by some other member. */
predicate isImplemented() { exists(this.getAnImplementor()) }
@@ -362,14 +339,59 @@ class Virtualizable extends Member, @virtualizable {
/** Holds if this member implements (transitively) an interface member. */
predicate implements() { exists(this.getAnUltimateImplementee()) }
/**
* Holds if this member overrides or implements (transitively)
* `that` member.
*/
predicate overridesOrImplements(Overridable that) {
this.getOverridee+() = that or
this.getAnUltimateImplementee() = that
}
/**
* Holds if this member overrides or implements (reflexively, transitively)
* `that` member.
*/
predicate overridesOrImplementsOrEquals(Virtualizable that) {
predicate overridesOrImplementsOrEquals(Overridable that) {
this = that or
this.getOverridee+() = that or
this.getAnUltimateImplementee() = that
this.overridesOrImplements(that)
}
}
/**
* A member where the `virtual` modifier is valid. That is, a method,
* a property, an indexer, or an event.
*
* Equivalently, these are the members that can be defined in an interface.
*
* Unlike `Overridable`, this class excludes accessors.
*/
class Virtualizable extends Overridable, Member, @virtualizable {
/** Holds if this member has the modifier `override`. */
predicate isOverride() { this.hasModifier("override") }
/** Holds if this member is `virtual`. */
predicate isVirtual() { this.hasModifier("virtual") }
override predicate isPublic() {
Member.super.isPublic() or
this.implementsExplicitInterface()
}
override predicate isPrivate() {
super.isPrivate() and
not this.implementsExplicitInterface()
}
override predicate isOverridableOrImplementable() {
not this.isSealed() and
not this.getDeclaringType().isSealed() and
(
this.isVirtual() or
this.isOverride() or
this.isAbstract() or
this.getDeclaringType() instanceof Interface
)
}
}

View File

@@ -315,7 +315,7 @@ class Indexer extends DeclarationWithGetSetAccessors, Parameterizable, @indexer
* An accessor. Either a getter (`Getter`), a setter (`Setter`), or event
* accessor (`EventAccessor`).
*/
class Accessor extends Callable, Modifiable, Attributable, @callable_accessor {
class Accessor extends Callable, Modifiable, Attributable, Overridable, @callable_accessor {
override ValueOrRefType getDeclaringType() { result = this.getDeclaration().getDeclaringType() }
/** Gets the assembly name of this accessor. */
@@ -376,6 +376,10 @@ class Accessor extends Callable, Modifiable, Attributable, @callable_accessor {
not (result instanceof AccessModifier and exists(this.getAnAccessModifier()))
}
override predicate isOverridableOrImplementable() {
this.getDeclaration().isOverridableOrImplementable()
}
override Accessor getUnboundDeclaration() { accessors(this, _, _, _, result) }
override Location getALocation() { accessor_location(this, result) }

View File

@@ -75,7 +75,7 @@ class BlockStmt extends Stmt, @block_stmt {
/** Holds if this block is the container of the global statements. */
predicate isGlobalStatementContainer() {
this.getEnclosingCallable().hasQualifiedName("<Program>$.<Main>$")
this.getEnclosingCallable().hasQualifiedName("Program.<Main>$")
}
override Stmt stripSingletonBlocks() {

View File

@@ -12,7 +12,12 @@ private class TypeRef extends @typeref {
string toString() { result = this.getName() }
Type getReferencedType() { typeref_type(this, result) }
Type getReferencedType() {
typeref_type(this, result)
or
not typeref_type(this, _) and
result instanceof UnknownType
}
}
/**

View File

@@ -8,7 +8,7 @@ class MainMethod extends Method {
(
this.hasName("Main")
or
this.hasQualifiedName("<Program>$", "<Main>$")
this.hasQualifiedName("Program.<Main>$")
) and
this.isStatic() and
(this.getReturnType() instanceof VoidType or this.getReturnType() instanceof IntType) and

View File

@@ -241,7 +241,7 @@ module ControlFlow {
predicate isBranch() { strictcount(this.getASuccessor()) > 1 }
/** Gets the enclosing callable of this control flow node. */
Callable getEnclosingCallable() { none() }
final Callable getEnclosingCallable() { result = getNodeCfgScope(this) }
}
/** Provides different types of control flow nodes. */
@@ -253,8 +253,6 @@ module ControlFlow {
override BasicBlocks::EntryBlock getBasicBlock() { result = Node.super.getBasicBlock() }
override Callable getEnclosingCallable() { result = this.getCallable() }
private Assignable getAssignable() { this = TEntryNode(result) }
override Location getLocation() {
@@ -283,8 +281,6 @@ module ControlFlow {
result = Node.super.getBasicBlock()
}
override Callable getEnclosingCallable() { result = this.getCallable() }
override Location getLocation() { result = scope.getLocation() }
override string toString() {
@@ -309,8 +305,6 @@ module ControlFlow {
override BasicBlocks::ExitBlock getBasicBlock() { result = Node.super.getBasicBlock() }
override Callable getEnclosingCallable() { result = this.getCallable() }
override Location getLocation() { result = scope.getLocation() }
override string toString() { result = "exit " + scope }
@@ -327,14 +321,7 @@ module ControlFlow {
private Splits splits;
private ControlFlowElement cfe;
ElementNode() { this = TElementNode(cfe, splits) }
override Callable getEnclosingCallable() {
result = cfe.getEnclosingCallable()
or
result =
this.getASplit().(Splitting::InitializerSplitting::InitializerSplit).getConstructor()
}
ElementNode() { this = TElementNode(_, cfe, splits) }
override ControlFlowElement getElement() { result = cfe }

View File

@@ -1086,7 +1086,7 @@ module Internal {
*/
private Callable customNullCheck(Parameter p, BooleanValue retVal, boolean isNull) {
result.getReturnType() instanceof BoolType and
not result.(Virtualizable).isOverridableOrImplementable() and
not result.(Overridable).isOverridableOrImplementable() and
p.getCallable() = result and
not p.isParams() and
p.getType() = any(Type t | t instanceof RefType or t instanceof NullableType) and

View File

@@ -342,7 +342,7 @@ private predicate succExitSplits(
ControlFlowElement pred, Splits predSplits, CfgScope succ, SuccessorType t
) {
exists(Reachability::SameSplitsBlock b, Completion c | pred = b.getAnElement() |
b.isReachable(predSplits) and
b.isReachable(succ, predSplits) and
t = getAMatchingSuccessorType(c) and
scopeLast(succ, pred, c) and
forall(SplitImpl predSplit | predSplit = predSplits.getASplit() |
@@ -399,7 +399,7 @@ private module SuccSplits {
ControlFlowElement succ, Completion c
) {
pred = b.getAnElement() and
b.isReachable(predSplits) and
b.isReachable(_, predSplits) and
succ(pred, succ, c)
}
@@ -728,12 +728,12 @@ private module Reachability {
* Holds if the elements of this block are reachable from a callable entry
* point, with the splits `splits`.
*/
predicate isReachable(Splits splits) {
predicate isReachable(CfgScope scope, Splits splits) {
// Base case
succEntrySplits(_, this, splits, _)
succEntrySplits(scope, this, splits, _)
or
// Recursive case
exists(SameSplitsBlock pred, Splits predSplits | pred.isReachable(predSplits) |
exists(SameSplitsBlock pred, Splits predSplits | pred.isReachable(scope, predSplits) |
this = pred.getASuccessor(predSplits, splits)
)
}
@@ -791,18 +791,20 @@ private module Cached {
newtype TCfgNode =
TEntryNode(CfgScope scope) { succEntrySplits(scope, _, _, _) } or
TAnnotatedExitNode(CfgScope scope, boolean normal) {
exists(Reachability::SameSplitsBlock b, SuccessorType t | b.isReachable(_) |
exists(Reachability::SameSplitsBlock b, SuccessorType t | b.isReachable(scope, _) |
succExitSplits(b.getAnElement(), _, scope, t) and
if isAbnormalExitType(t) then normal = false else normal = true
)
} or
TExitNode(CfgScope scope) {
exists(Reachability::SameSplitsBlock b | b.isReachable(_) |
exists(Reachability::SameSplitsBlock b | b.isReachable(scope, _) |
succExitSplits(b.getAnElement(), _, scope, _)
)
} or
TElementNode(ControlFlowElement cfe, Splits splits) {
exists(Reachability::SameSplitsBlock b | b.isReachable(splits) | cfe = b.getAnElement())
TElementNode(CfgScope scope, ControlFlowElement cfe, Splits splits) {
exists(Reachability::SameSplitsBlock b | b.isReachable(scope, splits) |
cfe = b.getAnElement()
)
}
/** Gets a successor node of a given flow type, if any. */
@@ -810,24 +812,24 @@ private module Cached {
TCfgNode getASuccessor(TCfgNode pred, SuccessorType t) {
// Callable entry node -> callable body
exists(ControlFlowElement succElement, Splits succSplits, CfgScope scope |
result = TElementNode(succElement, succSplits) and
result = TElementNode(scope, succElement, succSplits) and
pred = TEntryNode(scope) and
succEntrySplits(scope, succElement, succSplits, t)
)
or
exists(ControlFlowElement predElement, Splits predSplits |
pred = TElementNode(predElement, predSplits)
exists(CfgScope scope, ControlFlowElement predElement, Splits predSplits |
pred = TElementNode(pragma[only_bind_into](scope), predElement, predSplits)
|
// Element node -> callable exit (annotated)
exists(CfgScope scope, boolean normal |
result = TAnnotatedExitNode(scope, normal) and
exists(boolean normal |
result = TAnnotatedExitNode(pragma[only_bind_into](scope), normal) and
succExitSplits(predElement, predSplits, scope, t) and
if isAbnormalExitType(t) then normal = false else normal = true
)
or
// Element node -> element node
exists(ControlFlowElement succElement, Splits succSplits, Completion c |
result = TElementNode(succElement, succSplits)
result = TElementNode(pragma[only_bind_into](scope), succElement, succSplits)
|
succSplits(predElement, predSplits, succElement, succSplits, c) and
t = getAMatchingSuccessorType(c)
@@ -853,6 +855,23 @@ private module Cached {
*/
cached
ControlFlowElement getAControlFlowExitNode(ControlFlowElement cfe) { last(cfe, result, _) }
/**
* Gets the CFG scope of node `n`. Unlike `getCfgScope`, this predicate
* is calculated based on reachability from an entry node, and it may
* yield different results for AST elements that are split into multiple
* scopes.
*/
cached
CfgScope getNodeCfgScope(TCfgNode n) {
n = TEntryNode(result)
or
n = TAnnotatedExitNode(result, _)
or
n = TExitNode(result)
or
n = TElementNode(result, _, _)
}
}
import Cached
@@ -938,14 +957,45 @@ module Consistency {
not split.hasEntry(pred, succ, c)
}
private class SimpleSuccessorType extends SuccessorType {
SimpleSuccessorType() {
this = getAMatchingSuccessorType(any(Completion c | completionIsSimple(c)))
}
}
private class NormalSuccessorType extends SuccessorType {
NormalSuccessorType() {
this = getAMatchingSuccessorType(any(Completion c | completionIsNormal(c)))
}
}
query predicate multipleSuccessors(Node node, SuccessorType t, Node successor) {
not node instanceof TEntryNode and
strictcount(getASuccessor(node, t)) > 1 and
successor = getASuccessor(node, t)
successor = getASuccessor(node, t) and
// allow for functions with multiple bodies
not (t instanceof SimpleSuccessorType and node instanceof TEntryNode)
}
query predicate simpleAndNormalSuccessors(
Node node, NormalSuccessorType t1, SimpleSuccessorType t2, Node succ1, Node succ2
) {
t1 != t2 and
succ1 = getASuccessor(node, t1) and
succ2 = getASuccessor(node, t2)
}
query predicate deadEnd(Node node) {
not node instanceof TExitNode and
not exists(getASuccessor(node, _))
}
query predicate nonUniqueSplitKind(SplitImpl split, SplitKind sk) {
sk = split.getKind() and
strictcount(split.getKind()) > 1
}
query predicate nonUniqueListOrder(SplitKind sk, int ord) {
ord = sk.getListOrder() and
strictcount(sk.getListOrder()) > 1
}
}

View File

@@ -179,7 +179,7 @@ module InitializerSplitting {
*
* respectively.
*/
class InitializerSplit extends Split, TInitializerSplit {
private class InitializerSplit extends Split, TInitializerSplit {
private Constructor c;
InitializerSplit() { this = TInitializerSplit(c) }

View File

@@ -78,7 +78,6 @@ private import internal.DataFlowPublic
private import internal.FlowSummaryImpl::Public
private import internal.FlowSummaryImpl::Private::External
private import internal.FlowSummaryImplSpecific
private import semmle.code.csharp.dispatch.OverridableCallable
/**
* A module importing the frameworks that provide external flow data,
@@ -92,6 +91,17 @@ private module Frameworks {
private import semmle.code.csharp.frameworks.ServiceStack
private import semmle.code.csharp.frameworks.Sql
private import semmle.code.csharp.frameworks.EntityFramework
private import semmle.code.csharp.frameworks.system.Text
private import semmle.code.csharp.frameworks.system.Net
private import semmle.code.csharp.frameworks.system.Web
private import semmle.code.csharp.frameworks.system.collections.Generic
private import semmle.code.csharp.frameworks.system.web.ui.WebControls
private import semmle.code.csharp.frameworks.JsonNET
private import semmle.code.csharp.frameworks.system.IO
private import semmle.code.csharp.frameworks.system.io.Compression
private import semmle.code.csharp.frameworks.system.Xml
private import semmle.code.csharp.frameworks.system.threading.Tasks
private import semmle.code.csharp.frameworks.system.runtime.CompilerServices
}
/**
@@ -262,7 +272,7 @@ module CsvValidation {
not name.regexpMatch("[a-zA-Z0-9_<>,]*") and
msg = "Dubious member name \"" + name + "\" in " + pred + " model."
or
not signature.regexpMatch("|\\([a-zA-Z0-9_<>\\.\\+,\\[\\]]*\\)") and
not signature.regexpMatch("|\\([a-zA-Z0-9_<>\\.\\+\\*,\\[\\]]*\\)") and
msg = "Dubious signature \"" + signature + "\" in " + pred + " model."
or
not ext.regexpMatch("|Attribute") and
@@ -348,16 +358,17 @@ private class UnboundValueOrRefType extends ValueOrRefType {
}
}
private class UnboundCallable extends Callable {
/** An unbound callable. */
class UnboundCallable extends Callable {
UnboundCallable() { this.isUnboundDeclaration() }
/**
* Holds if this unbound callable overrides or implements (transitively)
* `that` unbound callable.
*/
predicate overridesOrImplementsUnbound(UnboundCallable that) {
exists(Callable c |
this.(Virtualizable).overridesOrImplementsOrEquals(c) or
this = c.(OverridableCallable).getAnUltimateImplementor() or
this = c.(OverridableCallable).getAnOverrider+()
|
this != c and
this.(Overridable).overridesOrImplements(c) and
that = c.getUnboundDeclaration()
)
}

View File

@@ -2,7 +2,11 @@
import csharp
private import internal.FlowSummaryImpl as Impl
private import internal.DataFlowDispatch
private import internal.DataFlowDispatch as DataFlowDispatch
class ParameterPosition = DataFlowDispatch::ParameterPosition;
class ArgumentPosition = DataFlowDispatch::ArgumentPosition;
// import all instances below
private module Summaries {
@@ -14,7 +18,27 @@ class SummaryComponent = Impl::Public::SummaryComponent;
/** Provides predicates for constructing summary components. */
module SummaryComponent {
import Impl::Public::SummaryComponent
private import Impl::Public::SummaryComponent as SummaryComponentInternal
predicate content = SummaryComponentInternal::content/1;
/** Gets a summary component for parameter `i`. */
SummaryComponent parameter(int i) {
exists(ArgumentPosition pos |
result = SummaryComponentInternal::parameter(pos) and
i = pos.getPosition()
)
}
/** Gets a summary component for argument `i`. */
SummaryComponent argument(int i) {
exists(ParameterPosition pos |
result = SummaryComponentInternal::argument(pos) and
i = pos.getPosition()
)
}
predicate return = SummaryComponentInternal::return/1;
/** Gets a summary component that represents a qualifier. */
SummaryComponent qualifier() { result = argument(-1) }
@@ -33,14 +57,14 @@ module SummaryComponent {
}
/** Gets a summary component that represents the return value of a call. */
SummaryComponent return() { result = return(any(NormalReturnKind rk)) }
SummaryComponent return() { result = return(any(DataFlowDispatch::NormalReturnKind rk)) }
/** Gets a summary component that represents a jump to `c`. */
SummaryComponent jump(Callable c) {
result =
return(any(JumpReturnKind jrk |
return(any(DataFlowDispatch::JumpReturnKind jrk |
jrk.getTarget() = c.getUnboundDeclaration() and
jrk.getTargetReturnKind() instanceof NormalReturnKind
jrk.getTargetReturnKind() instanceof DataFlowDispatch::NormalReturnKind
))
}
}
@@ -49,7 +73,16 @@ class SummaryComponentStack = Impl::Public::SummaryComponentStack;
/** Provides predicates for constructing stacks of summary components. */
module SummaryComponentStack {
import Impl::Public::SummaryComponentStack
private import Impl::Public::SummaryComponentStack as SummaryComponentStackInternal
predicate singleton = SummaryComponentStackInternal::singleton/1;
predicate push = SummaryComponentStackInternal::push/2;
/** Gets a singleton stack for argument `i`. */
SummaryComponentStack argument(int i) { result = singleton(SummaryComponent::argument(i)) }
predicate return = SummaryComponentStackInternal::return/1;
/** Gets a singleton stack representing a qualifier. */
SummaryComponentStack qualifier() { result = singleton(SummaryComponent::qualifier()) }
@@ -84,12 +117,12 @@ private class SummarizedCallableDefaultClearsContent extends Impl::Public::Summa
}
// By default, we assume that all stores into arguments are definite
override predicate clearsContent(int i, DataFlow::Content content) {
override predicate clearsContent(ParameterPosition pos, DataFlow::Content content) {
exists(SummaryComponentStack output |
this.propagatesFlow(_, output, _) and
output.drop(_) =
SummaryComponentStack::push(SummaryComponent::content(content),
SummaryComponentStack::argument(i)) and
SummaryComponentStack::argument(pos.getPosition())) and
not content instanceof DataFlow::ElementContent
)
}

View File

@@ -5,7 +5,7 @@ private import DataFlowImplCommon as DataFlowImplCommon
private import DataFlowPublic
private import DataFlowPrivate
private import FlowSummaryImpl as FlowSummaryImpl
private import semmle.code.csharp.dataflow.FlowSummary
private import semmle.code.csharp.dataflow.FlowSummary as FlowSummary
private import semmle.code.csharp.dataflow.ExternalFlow
private import semmle.code.csharp.dispatch.Dispatch
private import semmle.code.csharp.dispatch.RuntimeCallable
@@ -13,7 +13,7 @@ private import semmle.code.csharp.frameworks.system.Collections
private import semmle.code.csharp.frameworks.system.collections.Generic
private predicate summarizedCallable(DataFlowCallable c) {
c instanceof SummarizedCallable
c instanceof FlowSummary::SummarizedCallable
or
FlowSummaryImpl::Private::summaryReturnNode(_, TJumpReturnKind(c, _))
or
@@ -108,13 +108,27 @@ private module Cached {
// No need to include calls that are compiled from source
not call.getImplementation().getMethod().compiledFromSource()
} or
TSummaryCall(SummarizedCallable c, Node receiver) {
TSummaryCall(FlowSummary::SummarizedCallable c, Node receiver) {
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
}
/** Gets a viable run-time target for the call `call`. */
cached
DataFlowCallable viableCallable(DataFlowCall call) { result = call.getARuntimeTarget() }
private int parameterPosition() {
result =
[
-1, any(Parameter p).getPosition(),
ImplicitCapturedParameterNodeImpl::getParameterPosition(_)
]
}
cached
newtype TParameterPosition = MkParameterPosition(int i) { i = parameterPosition() }
cached
newtype TArgumentPosition = MkArgumentPosition(int i) { i = parameterPosition() }
}
import Cached
@@ -388,7 +402,7 @@ class CilDataFlowCall extends DataFlowCall, TCilCall {
* the method `Select`.
*/
class SummaryCall extends DelegateDataFlowCall, TSummaryCall {
private SummarizedCallable c;
private FlowSummary::SummarizedCallable c;
private Node receiver;
SummaryCall() { this = TSummaryCall(c, receiver) }
@@ -410,3 +424,37 @@ class SummaryCall extends DelegateDataFlowCall, TSummaryCall {
override Location getLocation() { result = c.getLocation() }
}
/** A parameter position represented by an integer. */
class ParameterPosition extends MkParameterPosition {
private int i;
ParameterPosition() { this = MkParameterPosition(i) }
/** Gets the underlying integer. */
int getPosition() { result = i }
/** Gets a textual representation of this position. */
string toString() { result = i.toString() }
}
/** An argument position represented by an integer. */
class ArgumentPosition extends MkArgumentPosition {
private int i;
ArgumentPosition() { this = MkArgumentPosition(i) }
/** Gets the underlying integer. */
int getPosition() { result = i }
/** Gets a textual representation of this position. */
string toString() { result = i.toString() }
}
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) {
exists(int i |
ppos = MkParameterPosition(i) and
apos = MkArgumentPosition(i)
)
}

View File

@@ -256,11 +256,11 @@ private class ArgNodeEx extends NodeEx {
private class ParamNodeEx extends NodeEx {
ParamNodeEx() { this.asNode() instanceof ParamNode }
predicate isParameterOf(DataFlowCallable c, int i) {
this.asNode().(ParamNode).isParameterOf(c, i)
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.asNode().(ParamNode).isParameterOf(c, pos)
}
int getPosition() { this.isParameterOf(_, result) }
ParameterPosition getPosition() { this.isParameterOf(_, result) }
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
@@ -1447,7 +1447,7 @@ private module Stage2 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2142,7 +2142,7 @@ private module Stage3 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2908,7 +2908,7 @@ private module Stage4 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2992,7 +2992,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
int getParameterPos() { p.isParameterOf(_, result) }
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
ParamNodeEx getParamNode() { result = p }
@@ -3639,39 +3639,40 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
Configuration config
PathNodeMid mid, ParameterPosition ppos, CallContext cc, DataFlowCall call, AccessPath ap,
AccessPathApprox apa, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
apa = ap.getApprox() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config
) {
exists(ParamNodeEx p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
p.isParameterOf(callable, pos)
)
}
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
AccessPath ap, Configuration config
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
pathIntoArg(mid, pragma[only_bind_into](pos), outercc, call, ap, pragma[only_bind_into](apa),
pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa),
pragma[only_bind_into](config))
)
}
@@ -3686,9 +3687,9 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
(
sc = TSummaryCtxSome(p, ap)
or
@@ -3712,7 +3713,7 @@ private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa,
Configuration config
) {
exists(PathNodeMid mid, RetNodeEx ret, int pos |
exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos |
mid.getNodeEx() = ret and
kind = ret.getKind() and
cc = mid.getCallContext() and
@@ -4441,24 +4442,25 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
PartialPathNodeFwd mid, ParameterPosition ppos, CallContext cc, DataFlowCall call,
PartialAccessPath ap, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc,
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, ap, config) and
partialPathIntoArg(mid, pos, outercc, call, ap, config) and
callable = resolveCall(call, outercc)
}
@@ -4467,9 +4469,9 @@ private module FlowExploration {
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
@@ -4633,22 +4635,23 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathFlowsThrough(
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
ArgumentPosition apos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2,
RevPartialAccessPath ap, Configuration config
) {
exists(PartialPathNodeRev mid, ParamNodeEx p |
exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos |
mid.getNodeEx() = p and
p.getPosition() = pos and
p.getPosition() = ppos and
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate revPartialPathThroughCallable0(
DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap,
DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, RevPartialAccessPath ap,
Configuration config
) {
exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 |
@@ -4661,7 +4664,7 @@ private module FlowExploration {
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
exists(DataFlowCall call, ArgumentPosition pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
node.asNode().(ArgNode).argumentOf(call, pos)
)

View File

@@ -256,11 +256,11 @@ private class ArgNodeEx extends NodeEx {
private class ParamNodeEx extends NodeEx {
ParamNodeEx() { this.asNode() instanceof ParamNode }
predicate isParameterOf(DataFlowCallable c, int i) {
this.asNode().(ParamNode).isParameterOf(c, i)
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.asNode().(ParamNode).isParameterOf(c, pos)
}
int getPosition() { this.isParameterOf(_, result) }
ParameterPosition getPosition() { this.isParameterOf(_, result) }
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
@@ -1447,7 +1447,7 @@ private module Stage2 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2142,7 +2142,7 @@ private module Stage3 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2908,7 +2908,7 @@ private module Stage4 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2992,7 +2992,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
int getParameterPos() { p.isParameterOf(_, result) }
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
ParamNodeEx getParamNode() { result = p }
@@ -3639,39 +3639,40 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
Configuration config
PathNodeMid mid, ParameterPosition ppos, CallContext cc, DataFlowCall call, AccessPath ap,
AccessPathApprox apa, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
apa = ap.getApprox() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config
) {
exists(ParamNodeEx p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
p.isParameterOf(callable, pos)
)
}
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
AccessPath ap, Configuration config
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
pathIntoArg(mid, pragma[only_bind_into](pos), outercc, call, ap, pragma[only_bind_into](apa),
pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa),
pragma[only_bind_into](config))
)
}
@@ -3686,9 +3687,9 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
(
sc = TSummaryCtxSome(p, ap)
or
@@ -3712,7 +3713,7 @@ private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa,
Configuration config
) {
exists(PathNodeMid mid, RetNodeEx ret, int pos |
exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos |
mid.getNodeEx() = ret and
kind = ret.getKind() and
cc = mid.getCallContext() and
@@ -4441,24 +4442,25 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
PartialPathNodeFwd mid, ParameterPosition ppos, CallContext cc, DataFlowCall call,
PartialAccessPath ap, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc,
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, ap, config) and
partialPathIntoArg(mid, pos, outercc, call, ap, config) and
callable = resolveCall(call, outercc)
}
@@ -4467,9 +4469,9 @@ private module FlowExploration {
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
@@ -4633,22 +4635,23 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathFlowsThrough(
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
ArgumentPosition apos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2,
RevPartialAccessPath ap, Configuration config
) {
exists(PartialPathNodeRev mid, ParamNodeEx p |
exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos |
mid.getNodeEx() = p and
p.getPosition() = pos and
p.getPosition() = ppos and
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate revPartialPathThroughCallable0(
DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap,
DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, RevPartialAccessPath ap,
Configuration config
) {
exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 |
@@ -4661,7 +4664,7 @@ private module FlowExploration {
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
exists(DataFlowCall call, ArgumentPosition pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
node.asNode().(ArgNode).argumentOf(call, pos)
)

View File

@@ -256,11 +256,11 @@ private class ArgNodeEx extends NodeEx {
private class ParamNodeEx extends NodeEx {
ParamNodeEx() { this.asNode() instanceof ParamNode }
predicate isParameterOf(DataFlowCallable c, int i) {
this.asNode().(ParamNode).isParameterOf(c, i)
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.asNode().(ParamNode).isParameterOf(c, pos)
}
int getPosition() { this.isParameterOf(_, result) }
ParameterPosition getPosition() { this.isParameterOf(_, result) }
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
@@ -1447,7 +1447,7 @@ private module Stage2 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2142,7 +2142,7 @@ private module Stage3 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2908,7 +2908,7 @@ private module Stage4 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2992,7 +2992,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
int getParameterPos() { p.isParameterOf(_, result) }
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
ParamNodeEx getParamNode() { result = p }
@@ -3639,39 +3639,40 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
Configuration config
PathNodeMid mid, ParameterPosition ppos, CallContext cc, DataFlowCall call, AccessPath ap,
AccessPathApprox apa, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
apa = ap.getApprox() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config
) {
exists(ParamNodeEx p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
p.isParameterOf(callable, pos)
)
}
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
AccessPath ap, Configuration config
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
pathIntoArg(mid, pragma[only_bind_into](pos), outercc, call, ap, pragma[only_bind_into](apa),
pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa),
pragma[only_bind_into](config))
)
}
@@ -3686,9 +3687,9 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
(
sc = TSummaryCtxSome(p, ap)
or
@@ -3712,7 +3713,7 @@ private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa,
Configuration config
) {
exists(PathNodeMid mid, RetNodeEx ret, int pos |
exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos |
mid.getNodeEx() = ret and
kind = ret.getKind() and
cc = mid.getCallContext() and
@@ -4441,24 +4442,25 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
PartialPathNodeFwd mid, ParameterPosition ppos, CallContext cc, DataFlowCall call,
PartialAccessPath ap, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc,
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, ap, config) and
partialPathIntoArg(mid, pos, outercc, call, ap, config) and
callable = resolveCall(call, outercc)
}
@@ -4467,9 +4469,9 @@ private module FlowExploration {
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
@@ -4633,22 +4635,23 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathFlowsThrough(
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
ArgumentPosition apos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2,
RevPartialAccessPath ap, Configuration config
) {
exists(PartialPathNodeRev mid, ParamNodeEx p |
exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos |
mid.getNodeEx() = p and
p.getPosition() = pos and
p.getPosition() = ppos and
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate revPartialPathThroughCallable0(
DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap,
DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, RevPartialAccessPath ap,
Configuration config
) {
exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 |
@@ -4661,7 +4664,7 @@ private module FlowExploration {
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
exists(DataFlowCall call, ArgumentPosition pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
node.asNode().(ArgNode).argumentOf(call, pos)
)

View File

@@ -256,11 +256,11 @@ private class ArgNodeEx extends NodeEx {
private class ParamNodeEx extends NodeEx {
ParamNodeEx() { this.asNode() instanceof ParamNode }
predicate isParameterOf(DataFlowCallable c, int i) {
this.asNode().(ParamNode).isParameterOf(c, i)
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.asNode().(ParamNode).isParameterOf(c, pos)
}
int getPosition() { this.isParameterOf(_, result) }
ParameterPosition getPosition() { this.isParameterOf(_, result) }
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
@@ -1447,7 +1447,7 @@ private module Stage2 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2142,7 +2142,7 @@ private module Stage3 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2908,7 +2908,7 @@ private module Stage4 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2992,7 +2992,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
int getParameterPos() { p.isParameterOf(_, result) }
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
ParamNodeEx getParamNode() { result = p }
@@ -3639,39 +3639,40 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
Configuration config
PathNodeMid mid, ParameterPosition ppos, CallContext cc, DataFlowCall call, AccessPath ap,
AccessPathApprox apa, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
apa = ap.getApprox() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config
) {
exists(ParamNodeEx p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
p.isParameterOf(callable, pos)
)
}
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
AccessPath ap, Configuration config
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
pathIntoArg(mid, pragma[only_bind_into](pos), outercc, call, ap, pragma[only_bind_into](apa),
pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa),
pragma[only_bind_into](config))
)
}
@@ -3686,9 +3687,9 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
(
sc = TSummaryCtxSome(p, ap)
or
@@ -3712,7 +3713,7 @@ private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa,
Configuration config
) {
exists(PathNodeMid mid, RetNodeEx ret, int pos |
exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos |
mid.getNodeEx() = ret and
kind = ret.getKind() and
cc = mid.getCallContext() and
@@ -4441,24 +4442,25 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
PartialPathNodeFwd mid, ParameterPosition ppos, CallContext cc, DataFlowCall call,
PartialAccessPath ap, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc,
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, ap, config) and
partialPathIntoArg(mid, pos, outercc, call, ap, config) and
callable = resolveCall(call, outercc)
}
@@ -4467,9 +4469,9 @@ private module FlowExploration {
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
@@ -4633,22 +4635,23 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathFlowsThrough(
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
ArgumentPosition apos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2,
RevPartialAccessPath ap, Configuration config
) {
exists(PartialPathNodeRev mid, ParamNodeEx p |
exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos |
mid.getNodeEx() = p and
p.getPosition() = pos and
p.getPosition() = ppos and
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate revPartialPathThroughCallable0(
DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap,
DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, RevPartialAccessPath ap,
Configuration config
) {
exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 |
@@ -4661,7 +4664,7 @@ private module FlowExploration {
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
exists(DataFlowCall call, ArgumentPosition pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
node.asNode().(ArgNode).argumentOf(call, pos)
)

View File

@@ -256,11 +256,11 @@ private class ArgNodeEx extends NodeEx {
private class ParamNodeEx extends NodeEx {
ParamNodeEx() { this.asNode() instanceof ParamNode }
predicate isParameterOf(DataFlowCallable c, int i) {
this.asNode().(ParamNode).isParameterOf(c, i)
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.asNode().(ParamNode).isParameterOf(c, pos)
}
int getPosition() { this.isParameterOf(_, result) }
ParameterPosition getPosition() { this.isParameterOf(_, result) }
predicate allowParameterReturnInSelf() { allowParameterReturnInSelfCached(this.asNode()) }
}
@@ -1447,7 +1447,7 @@ private module Stage2 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2142,7 +2142,7 @@ private module Stage3 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2908,7 +2908,7 @@ private module Stage4 {
}
predicate parameterMayFlowThrough(ParamNodeEx p, DataFlowCallable c, Ap ap, Configuration config) {
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, int pos |
exists(RetNodeEx ret, Ap ap0, ReturnKindExt kind, ParameterPosition pos |
parameterFlow(p, ap, ap0, c, config) and
c = ret.getEnclosingCallable() and
revFlow(pragma[only_bind_into](ret), true, apSome(_), pragma[only_bind_into](ap0),
@@ -2992,7 +2992,7 @@ private class SummaryCtxSome extends SummaryCtx, TSummaryCtxSome {
SummaryCtxSome() { this = TSummaryCtxSome(p, ap) }
int getParameterPos() { p.isParameterOf(_, result) }
ParameterPosition getParameterPos() { p.isParameterOf(_, result) }
ParamNodeEx getParamNode() { result = p }
@@ -3639,39 +3639,40 @@ private predicate pathOutOfCallable(PathNodeMid mid, NodeEx out, CallContext cc)
*/
pragma[noinline]
private predicate pathIntoArg(
PathNodeMid mid, int i, CallContext cc, DataFlowCall call, AccessPath ap, AccessPathApprox apa,
Configuration config
PathNodeMid mid, ParameterPosition ppos, CallContext cc, DataFlowCall call, AccessPath ap,
AccessPathApprox apa, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
apa = ap.getApprox() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate parameterCand(
DataFlowCallable callable, int i, AccessPathApprox apa, Configuration config
DataFlowCallable callable, ParameterPosition pos, AccessPathApprox apa, Configuration config
) {
exists(ParamNodeEx p |
Stage4::revFlow(p, _, _, apa, config) and
p.isParameterOf(callable, i)
p.isParameterOf(callable, pos)
)
}
pragma[nomagic]
private predicate pathIntoCallable0(
PathNodeMid mid, DataFlowCallable callable, int i, CallContext outercc, DataFlowCall call,
AccessPath ap, Configuration config
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, AccessPath ap, Configuration config
) {
exists(AccessPathApprox apa |
pathIntoArg(mid, pragma[only_bind_into](i), outercc, call, ap, pragma[only_bind_into](apa),
pathIntoArg(mid, pragma[only_bind_into](pos), outercc, call, ap, pragma[only_bind_into](apa),
pragma[only_bind_into](config)) and
callable = resolveCall(call, outercc) and
parameterCand(callable, pragma[only_bind_into](i), pragma[only_bind_into](apa),
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa),
pragma[only_bind_into](config))
)
}
@@ -3686,9 +3687,9 @@ private predicate pathIntoCallable(
PathNodeMid mid, ParamNodeEx p, CallContext outercc, CallContextCall innercc, SummaryCtx sc,
DataFlowCall call, Configuration config
) {
exists(int i, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable, AccessPath ap |
pathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
(
sc = TSummaryCtxSome(p, ap)
or
@@ -3712,7 +3713,7 @@ private predicate paramFlowsThrough(
ReturnKindExt kind, CallContextCall cc, SummaryCtxSome sc, AccessPath ap, AccessPathApprox apa,
Configuration config
) {
exists(PathNodeMid mid, RetNodeEx ret, int pos |
exists(PathNodeMid mid, RetNodeEx ret, ParameterPosition pos |
mid.getNodeEx() = ret and
kind = ret.getKind() and
cc = mid.getCallContext() and
@@ -4441,24 +4442,25 @@ private module FlowExploration {
pragma[noinline]
private predicate partialPathIntoArg(
PartialPathNodeFwd mid, int i, CallContext cc, DataFlowCall call, PartialAccessPath ap,
Configuration config
PartialPathNodeFwd mid, ParameterPosition ppos, CallContext cc, DataFlowCall call,
PartialAccessPath ap, Configuration config
) {
exists(ArgNode arg |
exists(ArgNode arg, ArgumentPosition apos |
arg = mid.getNodeEx().asNode() and
cc = mid.getCallContext() and
arg.argumentOf(call, i) and
arg.argumentOf(call, apos) and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate partialPathIntoCallable0(
PartialPathNodeFwd mid, DataFlowCallable callable, int i, CallContext outercc,
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, CallContext outercc,
DataFlowCall call, PartialAccessPath ap, Configuration config
) {
partialPathIntoArg(mid, i, outercc, call, ap, config) and
partialPathIntoArg(mid, pos, outercc, call, ap, config) and
callable = resolveCall(call, outercc)
}
@@ -4467,9 +4469,9 @@ private module FlowExploration {
TSummaryCtx1 sc1, TSummaryCtx2 sc2, DataFlowCall call, PartialAccessPath ap,
Configuration config
) {
exists(int i, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, i, outercc, call, ap, config) and
p.isParameterOf(callable, i) and
exists(ParameterPosition pos, DataFlowCallable callable |
partialPathIntoCallable0(mid, callable, pos, outercc, call, ap, config) and
p.isParameterOf(callable, pos) and
sc1 = TSummaryCtx1Param(p) and
sc2 = TSummaryCtx2Some(ap)
|
@@ -4633,22 +4635,23 @@ private module FlowExploration {
pragma[nomagic]
private predicate revPartialPathFlowsThrough(
int pos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, RevPartialAccessPath ap,
Configuration config
ArgumentPosition apos, TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2,
RevPartialAccessPath ap, Configuration config
) {
exists(PartialPathNodeRev mid, ParamNodeEx p |
exists(PartialPathNodeRev mid, ParamNodeEx p, ParameterPosition ppos |
mid.getNodeEx() = p and
p.getPosition() = pos and
p.getPosition() = ppos and
sc1 = mid.getSummaryCtx1() and
sc2 = mid.getSummaryCtx2() and
ap = mid.getAp() and
config = mid.getConfiguration()
config = mid.getConfiguration() and
parameterMatch(ppos, apos)
)
}
pragma[nomagic]
private predicate revPartialPathThroughCallable0(
DataFlowCall call, PartialPathNodeRev mid, int pos, RevPartialAccessPath ap,
DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, RevPartialAccessPath ap,
Configuration config
) {
exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2 |
@@ -4661,7 +4664,7 @@ private module FlowExploration {
private predicate revPartialPathThroughCallable(
PartialPathNodeRev mid, ArgNodeEx node, RevPartialAccessPath ap, Configuration config
) {
exists(DataFlowCall call, int pos |
exists(DataFlowCall call, ArgumentPosition pos |
revPartialPathThroughCallable0(call, mid, pos, ap, config) and
node.asNode().(ArgNode).argumentOf(call, pos)
)

View File

@@ -62,6 +62,18 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) {
tupleLimit = 1000
}
/**
* Holds if `arg` is an argument of `call` with an argument position that matches
* parameter position `ppos`.
*/
pragma[noinline]
predicate argumentPositionMatch(DataFlowCall call, ArgNode arg, ParameterPosition ppos) {
exists(ArgumentPosition apos |
arg.argumentOf(call, apos) and
parameterMatch(ppos, apos)
)
}
/**
* Provides a simple data-flow analysis for resolving lambda calls. The analysis
* currently excludes read-steps, store-steps, and flow-through.
@@ -71,25 +83,27 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) {
* calls. For this reason, we cannot reuse the code from `DataFlowImpl.qll` directly.
*/
private module LambdaFlow {
private predicate viableParamNonLambda(DataFlowCall call, int i, ParamNode p) {
p.isParameterOf(viableCallable(call), i)
pragma[noinline]
private predicate viableParamNonLambda(DataFlowCall call, ParameterPosition ppos, ParamNode p) {
p.isParameterOf(viableCallable(call), ppos)
}
private predicate viableParamLambda(DataFlowCall call, int i, ParamNode p) {
p.isParameterOf(viableCallableLambda(call, _), i)
pragma[noinline]
private predicate viableParamLambda(DataFlowCall call, ParameterPosition ppos, ParamNode p) {
p.isParameterOf(viableCallableLambda(call, _), ppos)
}
private predicate viableParamArgNonLambda(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(int i |
viableParamNonLambda(call, i, p) and
arg.argumentOf(call, i)
exists(ParameterPosition ppos |
viableParamNonLambda(call, ppos, p) and
argumentPositionMatch(call, arg, ppos)
)
}
private predicate viableParamArgLambda(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(int i |
viableParamLambda(call, i, p) and
arg.argumentOf(call, i)
exists(ParameterPosition ppos |
viableParamLambda(call, ppos, p) and
argumentPositionMatch(call, arg, ppos)
)
}
@@ -322,7 +336,7 @@ private module Cached {
or
exists(ArgNode arg |
result.(PostUpdateNode).getPreUpdateNode() = arg and
arg.argumentOf(call, k.(ParamUpdateReturnKind).getPosition())
arg.argumentOf(call, k.(ParamUpdateReturnKind).getAMatchingArgumentPosition())
)
}
@@ -330,7 +344,7 @@ private module Cached {
predicate returnNodeExt(Node n, ReturnKindExt k) {
k = TValueReturn(n.(ReturnNode).getKind())
or
exists(ParamNode p, int pos |
exists(ParamNode p, ParameterPosition pos |
parameterValueFlowsToPreUpdate(p, n) and
p.isParameterOf(_, pos) and
k = TParamUpdate(pos)
@@ -352,11 +366,13 @@ private module Cached {
}
cached
predicate parameterNode(Node p, DataFlowCallable c, int pos) { isParameterNode(p, c, pos) }
predicate parameterNode(Node p, DataFlowCallable c, ParameterPosition pos) {
isParameterNode(p, c, pos)
}
cached
predicate argumentNode(Node n, DataFlowCall call, int pos) {
n.(ArgumentNode).argumentOf(call, pos)
predicate argumentNode(Node n, DataFlowCall call, ArgumentPosition pos) {
isArgumentNode(n, call, pos)
}
/**
@@ -374,12 +390,12 @@ private module Cached {
}
/**
* Holds if `p` is the `i`th parameter of a viable dispatch target of `call`.
* The instance parameter is considered to have index `-1`.
* Holds if `p` is the parameter of a viable dispatch target of `call`,
* and `p` has position `ppos`.
*/
pragma[nomagic]
private predicate viableParam(DataFlowCall call, int i, ParamNode p) {
p.isParameterOf(viableCallableExt(call), i)
private predicate viableParam(DataFlowCall call, ParameterPosition ppos, ParamNode p) {
p.isParameterOf(viableCallableExt(call), ppos)
}
/**
@@ -388,9 +404,9 @@ private module Cached {
*/
cached
predicate viableParamArg(DataFlowCall call, ParamNode p, ArgNode arg) {
exists(int i |
viableParam(call, i, p) and
arg.argumentOf(call, i) and
exists(ParameterPosition ppos |
viableParam(call, ppos, p) and
argumentPositionMatch(call, arg, ppos) and
compatibleTypes(getNodeDataFlowType(arg), getNodeDataFlowType(p))
)
}
@@ -862,7 +878,7 @@ private module Cached {
cached
newtype TReturnKindExt =
TValueReturn(ReturnKind kind) or
TParamUpdate(int pos) { exists(ParamNode p | p.isParameterOf(_, pos)) }
TParamUpdate(ParameterPosition pos) { exists(ParamNode p | p.isParameterOf(_, pos)) }
cached
newtype TBooleanOption =
@@ -1054,9 +1070,9 @@ class ParamNode extends Node {
/**
* Holds if this node is the parameter of callable `c` at the specified
* (zero-based) position.
* position.
*/
predicate isParameterOf(DataFlowCallable c, int i) { parameterNode(this, c, i) }
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { parameterNode(this, c, pos) }
}
/** A data-flow node that represents a call argument. */
@@ -1064,7 +1080,9 @@ class ArgNode extends Node {
ArgNode() { argumentNode(this, _, _) }
/** Holds if this argument occurs at the given position in the given call. */
final predicate argumentOf(DataFlowCall call, int pos) { argumentNode(this, call, pos) }
final predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
argumentNode(this, call, pos)
}
}
/**
@@ -1110,11 +1128,14 @@ class ValueReturnKind extends ReturnKindExt, TValueReturn {
}
class ParamUpdateReturnKind extends ReturnKindExt, TParamUpdate {
private int pos;
private ParameterPosition pos;
ParamUpdateReturnKind() { this = TParamUpdate(pos) }
int getPosition() { result = pos }
ParameterPosition getPosition() { result = pos }
pragma[nomagic]
ArgumentPosition getAMatchingArgumentPosition() { parameterMatch(pos, result) }
override string toString() { result = "param update " + pos }
}

View File

@@ -6,7 +6,7 @@ private import DataFlowDispatch
private import DataFlowImplCommon
private import ControlFlowReachability
private import FlowSummaryImpl as FlowSummaryImpl
private import semmle.code.csharp.dataflow.FlowSummary
private import semmle.code.csharp.dataflow.FlowSummary as FlowSummary
private import semmle.code.csharp.Conversion
private import semmle.code.csharp.dataflow.internal.SsaImpl as SsaImpl
private import semmle.code.csharp.ExprOrStmtParent
@@ -22,7 +22,14 @@ private import semmle.code.csharp.frameworks.system.threading.Tasks
DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() }
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
predicate isParameterNode(ParameterNode p, DataFlowCallable c, int pos) { p.isParameterOf(c, pos) }
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) {
exists(int i | pos = MkParameterPosition(i) and p.isParameterOf(c, i))
}
/** Holds if `arg` is an `ArgumentNode` of `c` with position `pos`. */
predicate isArgumentNode(ArgumentNode arg, DataFlowCall c, ArgumentPosition pos) {
exists(int i | pos = MkArgumentPosition(i) and arg.argumentOf(c, i))
}
abstract class NodeImpl extends Node {
/** Do not call: use `getEnclosingCallable()` instead. */
@@ -494,9 +501,12 @@ private predicate fieldOrPropertyStore(Expr e, Content c, Expr src, Expr q, bool
f.isFieldLike() and
f instanceof InstanceFieldOrProperty
or
exists(SummarizedCallable callable, FlowSummaryImpl::Public::SummaryComponentStack input |
exists(
FlowSummary::SummarizedCallable callable,
FlowSummaryImpl::Public::SummaryComponentStack input
|
callable.propagatesFlow(input, _, _) and
input.contains(SummaryComponent::content(f.getContent()))
input.contains(FlowSummary::SummaryComponent::content(f.getContent()))
)
)
|
@@ -718,7 +728,7 @@ private module Cached {
cfn.getElement() = fla.getQualifier()
)
} or
TSummaryNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
TSummaryNode(FlowSummary::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
FlowSummaryImpl::Private::summaryNodeRange(c, state)
} or
TParamsArgumentNode(ControlFlow::Node callCfn) {
@@ -749,7 +759,8 @@ private module Cached {
newtype TContent =
TFieldContent(Field f) { f.isUnboundDeclaration() } or
TPropertyContent(Property p) { p.isUnboundDeclaration() } or
TElementContent()
TElementContent() or
TSyntheticFieldContent(SyntheticField f)
pragma[nomagic]
private predicate commonSubTypeGeneral(DataFlowTypeOrUnifiable t1, RelevantDataFlowType t2) {
@@ -794,11 +805,13 @@ predicate nodeIsHidden(Node n) {
exists(Parameter p | p = n.(ParameterNode).getParameter() |
not p.fromSource()
or
p.getCallable() instanceof SummarizedCallable
p.getCallable() instanceof FlowSummary::SummarizedCallable
)
or
n =
TInstanceParameterNode(any(Callable c | not c.fromSource() or c instanceof SummarizedCallable))
TInstanceParameterNode(any(Callable c |
not c.fromSource() or c instanceof FlowSummary::SummarizedCallable
))
or
n instanceof YieldReturnNode
or
@@ -1131,7 +1144,10 @@ private module ArgumentNodes {
SummaryArgumentNode() { FlowSummaryImpl::Private::summaryArgumentNode(_, this, _) }
override predicate argumentOf(DataFlowCall call, int pos) {
FlowSummaryImpl::Private::summaryArgumentNode(call, this, pos)
exists(ArgumentPosition apos |
FlowSummaryImpl::Private::summaryArgumentNode(call, this, apos) and
apos.getPosition() = pos
)
}
}
}
@@ -1421,7 +1437,7 @@ import OutNodes
/** A data-flow node used to model flow summaries. */
private class SummaryNode extends NodeImpl, TSummaryNode {
private SummarizedCallable c;
private FlowSummary::SummarizedCallable c;
private FlowSummaryImpl::Private::SummaryNodeState state;
SummaryNode() { this = TSummaryNode(c, state) }
@@ -1764,6 +1780,10 @@ private class DataFlowNullType extends DataFlowType {
}
}
private class DataFlowUnknownType extends DataFlowType {
DataFlowUnknownType() { this = Gvn::getGlobalValueNumber(any(UnknownType ut)) }
}
/**
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
* a node of type `t1` to a node of type `t2`.
@@ -1783,6 +1803,10 @@ predicate compatibleTypes(DataFlowType t1, DataFlowType t2) {
t1 instanceof Gvn::TypeParameterGvnType
or
t2 instanceof Gvn::TypeParameterGvnType
or
t1 instanceof DataFlowUnknownType
or
t2 instanceof DataFlowUnknownType
}
/**
@@ -2023,3 +2047,12 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves
predicate allowParameterReturnInSelf(ParameterNode p) {
FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(p)
}
/** A synthetic field. */
abstract class SyntheticField extends string {
bindingset[this]
SyntheticField() { any() }
/** Gets the type of this synthetic field. */
Type getType() { result instanceof ObjectType }
}

View File

@@ -224,6 +224,18 @@ class FieldContent extends Content, TFieldContent {
deprecated override Gvn::GvnType getType() { result = Gvn::getGlobalValueNumber(f.getType()) }
}
/** A reference to a synthetic field. */
class SyntheticFieldContent extends Content, TSyntheticFieldContent {
private SyntheticField f;
SyntheticFieldContent() { this = TSyntheticFieldContent(f) }
/** Gets the underlying synthetic field. */
SyntheticField getField() { result = f }
override string toString() { result = "synthetic " + f.toString() }
}
/** A reference to a property. */
class PropertyContent extends Content, TPropertyContent {
private Property p;

View File

@@ -12,7 +12,6 @@ private import semmle.code.csharp.dataflow.CallContext
private import semmle.code.csharp.dataflow.internal.DataFlowDispatch
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate
private import semmle.code.csharp.dataflow.internal.DataFlowPublic
private import semmle.code.csharp.dataflow.FlowSummary
private import semmle.code.csharp.dispatch.Dispatch
private import semmle.code.csharp.frameworks.system.linq.Expressions

View File

@@ -26,9 +26,13 @@ module Public {
string toString() {
exists(Content c | this = TContentSummaryComponent(c) and result = c.toString())
or
exists(int i | this = TParameterSummaryComponent(i) and result = "parameter " + i)
exists(ArgumentPosition pos |
this = TParameterSummaryComponent(pos) and result = "parameter " + pos
)
or
exists(int i | this = TArgumentSummaryComponent(i) and result = "argument " + i)
exists(ParameterPosition pos |
this = TArgumentSummaryComponent(pos) and result = "argument " + pos
)
or
exists(ReturnKind rk | this = TReturnSummaryComponent(rk) and result = "return (" + rk + ")")
}
@@ -39,11 +43,11 @@ module Public {
/** Gets a summary component for content `c`. */
SummaryComponent content(Content c) { result = TContentSummaryComponent(c) }
/** Gets a summary component for parameter `i`. */
SummaryComponent parameter(int i) { result = TParameterSummaryComponent(i) }
/** Gets a summary component for a parameter at position `pos`. */
SummaryComponent parameter(ArgumentPosition pos) { result = TParameterSummaryComponent(pos) }
/** Gets a summary component for argument `i`. */
SummaryComponent argument(int i) { result = TArgumentSummaryComponent(i) }
/** Gets a summary component for an argument at position `pos`. */
SummaryComponent argument(ParameterPosition pos) { result = TArgumentSummaryComponent(pos) }
/** Gets a summary component for a return of kind `rk`. */
SummaryComponent return(ReturnKind rk) { result = TReturnSummaryComponent(rk) }
@@ -120,8 +124,10 @@ module Public {
result = TConsSummaryComponentStack(head, tail)
}
/** Gets a singleton stack for argument `i`. */
SummaryComponentStack argument(int i) { result = singleton(SummaryComponent::argument(i)) }
/** Gets a singleton stack for an argument at position `pos`. */
SummaryComponentStack argument(ParameterPosition pos) {
result = singleton(SummaryComponent::argument(pos))
}
/** Gets a singleton stack representing a return of kind `rk`. */
SummaryComponentStack return(ReturnKind rk) { result = singleton(SummaryComponent::return(rk)) }
@@ -137,9 +143,15 @@ module Public {
or
noComponentSpecificCsv(sc) and
(
exists(int i | sc = TParameterSummaryComponent(i) and result = "Parameter[" + i + "]")
exists(ArgumentPosition pos |
sc = TParameterSummaryComponent(pos) and
result = "Parameter[" + getArgumentPositionCsv(pos) + "]"
)
or
exists(int i | sc = TArgumentSummaryComponent(i) and result = "Argument[" + i + "]")
exists(ParameterPosition pos |
sc = TArgumentSummaryComponent(pos) and
result = "Argument[" + getParameterPositionCsv(pos) + "]"
)
or
sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue"
)
@@ -201,10 +213,10 @@ module Public {
/**
* Holds if values stored inside `content` are cleared on objects passed as
* the `i`th argument to this callable.
* arguments at position `pos` to this callable.
*/
pragma[nomagic]
predicate clearsContent(int i, Content content) { none() }
predicate clearsContent(ParameterPosition pos, Content content) { none() }
}
}
@@ -217,11 +229,11 @@ module Private {
newtype TSummaryComponent =
TContentSummaryComponent(Content c) or
TParameterSummaryComponent(int i) { parameterPosition(i) } or
TArgumentSummaryComponent(int i) { parameterPosition(i) } or
TParameterSummaryComponent(ArgumentPosition pos) or
TArgumentSummaryComponent(ParameterPosition pos) or
TReturnSummaryComponent(ReturnKind rk)
private TSummaryComponent thisParam() {
private TParameterSummaryComponent thisParam() {
result = TParameterSummaryComponent(instanceParameterPosition())
}
@@ -285,9 +297,9 @@ module Private {
/**
* Holds if `c` has a flow summary from `input` to `arg`, where `arg`
* writes to (contents of) the `i`th argument, and `c` has a
* value-preserving flow summary from the `i`th argument to a return value
* (`return`).
* writes to (contents of) arguments at position `pos`, and `c` has a
* value-preserving flow summary from the arguments at position `pos`
* to a return value (`return`).
*
* In such a case, we derive flow from `input` to (contents of) the return
* value.
@@ -302,10 +314,10 @@ module Private {
SummarizedCallable c, SummaryComponentStack input, SummaryComponentStack arg,
SummaryComponentStack return, boolean preservesValue
) {
exists(int i |
exists(ParameterPosition pos |
summary(c, input, arg, preservesValue) and
isContentOfArgument(arg, i) and
summary(c, SummaryComponentStack::singleton(TArgumentSummaryComponent(i)), return, true) and
isContentOfArgument(arg, pos) and
summary(c, SummaryComponentStack::argument(pos), return, true) and
return.bottom() = TReturnSummaryComponent(_)
)
}
@@ -330,10 +342,10 @@ module Private {
s.head() = TParameterSummaryComponent(_) and exists(s.tail())
}
private predicate isContentOfArgument(SummaryComponentStack s, int i) {
s.head() = TContentSummaryComponent(_) and isContentOfArgument(s.tail(), i)
private predicate isContentOfArgument(SummaryComponentStack s, ParameterPosition pos) {
s.head() = TContentSummaryComponent(_) and isContentOfArgument(s.tail(), pos)
or
s = TSingletonSummaryComponentStack(TArgumentSummaryComponent(i))
s = SummaryComponentStack::argument(pos)
}
private predicate outputState(SummarizedCallable c, SummaryComponentStack s) {
@@ -364,8 +376,8 @@ module Private {
private newtype TSummaryNodeState =
TSummaryNodeInputState(SummaryComponentStack s) { inputState(_, s) } or
TSummaryNodeOutputState(SummaryComponentStack s) { outputState(_, s) } or
TSummaryNodeClearsContentState(int i, boolean post) {
any(SummarizedCallable sc).clearsContent(i, _) and post in [false, true]
TSummaryNodeClearsContentState(ParameterPosition pos, boolean post) {
any(SummarizedCallable sc).clearsContent(pos, _) and post in [false, true]
}
/**
@@ -414,21 +426,23 @@ module Private {
result = "to write: " + s
)
or
exists(int i, boolean post, string postStr |
this = TSummaryNodeClearsContentState(i, post) and
exists(ParameterPosition pos, boolean post, string postStr |
this = TSummaryNodeClearsContentState(pos, post) and
(if post = true then postStr = " (post)" else postStr = "") and
result = "clear: " + i + postStr
result = "clear: " + pos + postStr
)
}
}
/**
* Holds if `state` represents having read the `i`th argument for `c`. In this case
* we are not synthesizing a data-flow node, but instead assume that a relevant
* parameter node already exists.
* Holds if `state` represents having read from a parameter at position
* `pos` in `c`. In this case we are not synthesizing a data-flow node,
* but instead assume that a relevant parameter node already exists.
*/
private predicate parameterReadState(SummarizedCallable c, SummaryNodeState state, int i) {
state.isInputState(c, SummaryComponentStack::argument(i))
private predicate parameterReadState(
SummarizedCallable c, SummaryNodeState state, ParameterPosition pos
) {
state.isInputState(c, SummaryComponentStack::argument(pos))
}
/**
@@ -441,9 +455,9 @@ module Private {
or
state.isOutputState(c, _)
or
exists(int i |
c.clearsContent(i, _) and
state = TSummaryNodeClearsContentState(i, _)
exists(ParameterPosition pos |
c.clearsContent(pos, _) and
state = TSummaryNodeClearsContentState(pos, _)
)
}
@@ -452,9 +466,9 @@ module Private {
exists(SummaryNodeState state | state.isInputState(c, s) |
result = summaryNode(c, state)
or
exists(int i |
parameterReadState(c, state, i) and
result.(ParamNode).isParameterOf(c, i)
exists(ParameterPosition pos |
parameterReadState(c, state, pos) and
result.(ParamNode).isParameterOf(c, pos)
)
)
}
@@ -468,20 +482,20 @@ module Private {
}
/**
* Holds if a write targets `post`, which is a post-update node for the `i`th
* parameter of `c`.
* Holds if a write targets `post`, which is a post-update node for a
* parameter at position `pos` in `c`.
*/
private predicate isParameterPostUpdate(Node post, SummarizedCallable c, int i) {
post = summaryNodeOutputState(c, SummaryComponentStack::argument(i))
private predicate isParameterPostUpdate(Node post, SummarizedCallable c, ParameterPosition pos) {
post = summaryNodeOutputState(c, SummaryComponentStack::argument(pos))
}
/** Holds if a parameter node is required for the `i`th parameter of `c`. */
predicate summaryParameterNodeRange(SummarizedCallable c, int i) {
parameterReadState(c, _, i)
/** Holds if a parameter node at position `pos` is required for `c`. */
predicate summaryParameterNodeRange(SummarizedCallable c, ParameterPosition pos) {
parameterReadState(c, _, pos)
or
isParameterPostUpdate(_, c, i)
isParameterPostUpdate(_, c, pos)
or
c.clearsContent(i, _)
c.clearsContent(pos, _)
}
private predicate callbackOutput(
@@ -493,10 +507,10 @@ module Private {
}
private predicate callbackInput(
SummarizedCallable c, SummaryComponentStack s, Node receiver, int i
SummarizedCallable c, SummaryComponentStack s, Node receiver, ArgumentPosition pos
) {
any(SummaryNodeState state).isOutputState(c, s) and
s.head() = TParameterSummaryComponent(i) and
s.head() = TParameterSummaryComponent(pos) and
receiver = summaryNodeInputState(c, s.drop(1))
}
@@ -547,17 +561,17 @@ module Private {
result = getReturnType(c, rk)
)
or
exists(int i | head = TParameterSummaryComponent(i) |
exists(ArgumentPosition pos | head = TParameterSummaryComponent(pos) |
result =
getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
s.drop(1))), i)
s.drop(1))), pos)
)
)
)
or
exists(SummarizedCallable c, int i, ParamNode p |
n = summaryNode(c, TSummaryNodeClearsContentState(i, false)) and
p.isParameterOf(c, i) and
exists(SummarizedCallable c, ParameterPosition pos, ParamNode p |
n = summaryNode(c, TSummaryNodeClearsContentState(pos, false)) and
p.isParameterOf(c, pos) and
result = getNodeType(p)
)
}
@@ -571,10 +585,10 @@ module Private {
)
}
/** Holds if summary node `arg` is the `i`th argument of call `c`. */
predicate summaryArgumentNode(DataFlowCall c, Node arg, int i) {
/** Holds if summary node `arg` is at position `pos` in the call `c`. */
predicate summaryArgumentNode(DataFlowCall c, Node arg, ArgumentPosition pos) {
exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver |
callbackInput(callable, s, receiver, i) and
callbackInput(callable, s, receiver, pos) and
arg = summaryNodeOutputState(callable, s) and
c = summaryDataFlowCall(receiver)
)
@@ -582,12 +596,12 @@ module Private {
/** Holds if summary node `post` is a post-update node with pre-update node `pre`. */
predicate summaryPostUpdateNode(Node post, Node pre) {
exists(SummarizedCallable c, int i |
isParameterPostUpdate(post, c, i) and
pre.(ParamNode).isParameterOf(c, i)
exists(SummarizedCallable c, ParameterPosition pos |
isParameterPostUpdate(post, c, pos) and
pre.(ParamNode).isParameterOf(c, pos)
or
pre = summaryNode(c, TSummaryNodeClearsContentState(i, false)) and
post = summaryNode(c, TSummaryNodeClearsContentState(i, true))
pre = summaryNode(c, TSummaryNodeClearsContentState(pos, false)) and
post = summaryNode(c, TSummaryNodeClearsContentState(pos, true))
)
or
exists(SummarizedCallable callable, SummaryComponentStack s |
@@ -610,13 +624,13 @@ module Private {
* node, and back out to `p`.
*/
predicate summaryAllowParameterReturnInSelf(ParamNode p) {
exists(SummarizedCallable c, int i | p.isParameterOf(c, i) |
c.clearsContent(i, _)
exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(c, ppos) |
c.clearsContent(ppos, _)
or
exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents |
summary(c, inputContents, outputContents, _) and
inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(i)) and
outputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(i))
inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and
outputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos))
)
)
}
@@ -641,9 +655,9 @@ module Private {
preservesValue = false and not summary(c, inputContents, outputContents, true)
)
or
exists(SummarizedCallable c, int i |
pred.(ParamNode).isParameterOf(c, i) and
succ = summaryNode(c, TSummaryNodeClearsContentState(i, _)) and
exists(SummarizedCallable c, ParameterPosition pos |
pred.(ParamNode).isParameterOf(c, pos) and
succ = summaryNode(c, TSummaryNodeClearsContentState(pos, _)) and
preservesValue = true
)
}
@@ -692,12 +706,20 @@ module Private {
* node where field `b` is cleared).
*/
predicate summaryClearsContent(Node n, Content c) {
exists(SummarizedCallable sc, int i |
n = summaryNode(sc, TSummaryNodeClearsContentState(i, true)) and
sc.clearsContent(i, c)
exists(SummarizedCallable sc, ParameterPosition pos |
n = summaryNode(sc, TSummaryNodeClearsContentState(pos, true)) and
sc.clearsContent(pos, c)
)
}
pragma[noinline]
private predicate viableParam(
DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p
) {
p.isParameterOf(sc, ppos) and
sc = viableCallable(call)
}
/**
* Holds if values stored inside content `c` are cleared inside a
* callable to which `arg` is an argument.
@@ -706,18 +728,18 @@ module Private {
* `arg` (see comment for `summaryClearsContent`).
*/
predicate summaryClearsContentArg(ArgNode arg, Content c) {
exists(DataFlowCall call, int i |
viableCallable(call).(SummarizedCallable).clearsContent(i, c) and
arg.argumentOf(call, i)
exists(DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos |
argumentPositionMatch(call, arg, ppos) and
viableParam(call, sc, ppos, _) and
sc.clearsContent(ppos, c)
)
}
pragma[nomagic]
private ParamNode summaryArgParam(ArgNode arg, ReturnKindExt rk, OutNodeExt out) {
exists(DataFlowCall call, int pos, SummarizedCallable callable |
arg.argumentOf(call, pos) and
viableCallable(call) = callable and
result.isParameterOf(callable, pos) and
exists(DataFlowCall call, ParameterPosition ppos, SummarizedCallable sc |
argumentPositionMatch(call, arg, ppos) and
viableParam(call, sc, ppos, result) and
out = rk.getAnOutNode(call)
)
}
@@ -795,39 +817,33 @@ module Private {
}
/** Holds if specification component `c` parses as parameter `n`. */
predicate parseParam(string c, int n) {
predicate parseParam(string c, ArgumentPosition pos) {
specSplit(_, c, _) and
(
c.regexpCapture("Parameter\\[([-0-9]+)\\]", 1).toInt() = n
or
exists(int n1, int n2 |
c.regexpCapture("Parameter\\[([-0-9]+)\\.\\.([0-9]+)\\]", 1).toInt() = n1 and
c.regexpCapture("Parameter\\[([-0-9]+)\\.\\.([0-9]+)\\]", 2).toInt() = n2 and
n = [n1 .. n2]
)
exists(string body |
body = c.regexpCapture("Parameter\\[([^\\]]*)\\]", 1) and
pos = parseParamBody(body)
)
}
/** Holds if specification component `c` parses as argument `n`. */
predicate parseArg(string c, int n) {
predicate parseArg(string c, ParameterPosition pos) {
specSplit(_, c, _) and
(
c.regexpCapture("Argument\\[([-0-9]+)\\]", 1).toInt() = n
or
exists(int n1, int n2 |
c.regexpCapture("Argument\\[([-0-9]+)\\.\\.([0-9]+)\\]", 1).toInt() = n1 and
c.regexpCapture("Argument\\[([-0-9]+)\\.\\.([0-9]+)\\]", 2).toInt() = n2 and
n = [n1 .. n2]
)
exists(string body |
body = c.regexpCapture("Argument\\[([^\\]]*)\\]", 1) and
pos = parseArgBody(body)
)
}
private SummaryComponent interpretComponent(string c) {
specSplit(_, c, _) and
(
exists(int pos | parseArg(c, pos) and result = SummaryComponent::argument(pos))
exists(ParameterPosition pos |
parseArg(c, pos) and result = SummaryComponent::argument(pos)
)
or
exists(int pos | parseParam(c, pos) and result = SummaryComponent::parameter(pos))
exists(ArgumentPosition pos |
parseParam(c, pos) and result = SummaryComponent::parameter(pos)
)
or
c = "ReturnValue" and result = SummaryComponent::return(getReturnValueKind())
or
@@ -934,14 +950,18 @@ module Private {
interpretOutput(output, idx + 1, ref, mid) and
specSplit(output, c, idx)
|
exists(int pos |
node.asNode().(PostUpdateNode).getPreUpdateNode().(ArgNode).argumentOf(mid.asCall(), pos)
exists(ArgumentPosition apos, ParameterPosition ppos |
node.asNode().(PostUpdateNode).getPreUpdateNode().(ArgNode).argumentOf(mid.asCall(), apos) and
parameterMatch(ppos, apos)
|
c = "Argument" or parseArg(c, pos)
c = "Argument" or parseArg(c, ppos)
)
or
exists(int pos | node.asNode().(ParamNode).isParameterOf(mid.asCallable(), pos) |
c = "Parameter" or parseParam(c, pos)
exists(ArgumentPosition apos, ParameterPosition ppos |
node.asNode().(ParamNode).isParameterOf(mid.asCallable(), ppos) and
parameterMatch(ppos, apos)
|
c = "Parameter" or parseParam(c, apos)
)
or
c = "ReturnValue" and
@@ -960,8 +980,11 @@ module Private {
interpretInput(input, idx + 1, ref, mid) and
specSplit(input, c, idx)
|
exists(int pos | node.asNode().(ArgNode).argumentOf(mid.asCall(), pos) |
c = "Argument" or parseArg(c, pos)
exists(ArgumentPosition apos, ParameterPosition ppos |
node.asNode().(ArgNode).argumentOf(mid.asCall(), apos) and
parameterMatch(ppos, apos)
|
c = "Argument" or parseArg(c, ppos)
)
or
exists(ReturnNodeExt ret |
@@ -1117,9 +1140,9 @@ module Private {
b.asCall() = summaryDataFlowCall(a.asNode()) and
value = "receiver"
or
exists(int i |
summaryArgumentNode(b.asCall(), a.asNode(), i) and
value = "argument (" + i + ")"
exists(ArgumentPosition pos |
summaryArgumentNode(b.asCall(), a.asNode(), pos) and
value = "argument (" + pos + ")"
)
}

View File

@@ -13,11 +13,8 @@ private import FlowSummaryImpl::Public
private import semmle.code.csharp.Unification
private import semmle.code.csharp.dataflow.ExternalFlow
/** Holds is `i` is a valid parameter position. */
predicate parameterPosition(int i) { i in [-1 .. any(Parameter p).getPosition()] }
/** Gets the parameter position of the instance parameter. */
int instanceParameterPosition() { none() } // disables implicit summary flow to `this` for callbacks
ArgumentPosition instanceParameterPosition() { none() } // disables implicit summary flow to `this` for callbacks
/** Gets the synthesized summary data-flow node for the given values. */
Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = TSummaryNode(c, state) }
@@ -32,6 +29,8 @@ DataFlowType getContentType(Content c) {
or
t = c.(PropertyContent).getProperty().getType()
or
t = c.(SyntheticFieldContent).getField().getType()
or
c instanceof ElementContent and
t instanceof ObjectType // we don't know what the actual element type is
)
@@ -61,13 +60,14 @@ DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) {
}
/**
* Gets the type of the `i`th parameter in a synthesized call that targets a
* callback of type `t`.
* Gets the type of the parameter matching arguments at position `pos` in a
* synthesized call that targets a callback of type `t`.
*/
DataFlowType getCallbackParameterType(DataFlowType t, int i) {
DataFlowType getCallbackParameterType(DataFlowType t, ArgumentPosition pos) {
exists(SystemLinqExpressions::DelegateExtType dt |
t = Gvn::getGlobalValueNumber(dt) and
result = Gvn::getGlobalValueNumber(dt.getDelegateType().getParameter(i).getType())
result =
Gvn::getGlobalValueNumber(dt.getDelegateType().getParameter(pos.getPosition()).getType())
)
}
@@ -136,6 +136,11 @@ SummaryComponent interpretComponentSpecific(string c) {
c.regexpCapture("Property\\[(.+)\\]", 1) = p.getQualifiedName() and
result = SummaryComponent::content(any(PropertyContent pc | pc.getProperty() = p))
)
or
exists(SyntheticField f |
c.regexpCapture("SyntheticField\\[(.+)\\]", 1) = f and
result = SummaryComponent::content(any(SyntheticFieldContent sfc | sfc.getField() = f))
)
}
/** Gets the textual representation of the content in the format used for flow summaries. */
@@ -145,6 +150,8 @@ private string getContentSpecificCsv(Content c) {
exists(Field f | c = TFieldContent(f) and result = "Field[" + f.getQualifiedName() + "]")
or
exists(Property p | c = TPropertyContent(p) and result = "Property[" + p.getQualifiedName() + "]")
or
exists(SyntheticField f | c = TSyntheticFieldContent(f) and result = "SyntheticField[" + f + "]")
}
/** Gets the textual representation of a summary component in the format used for flow summaries. */
@@ -158,6 +165,12 @@ string getComponentSpecificCsv(SummaryComponent sc) {
)
}
/** Gets the textual representation of a parameter position in the format used for flow summaries. */
string getParameterPositionCsv(ParameterPosition pos) { result = pos.toString() }
/** Gets the textual representation of an argument position in the format used for flow summaries. */
string getArgumentPositionCsv(ArgumentPosition pos) { result = pos.toString() }
class SourceOrSinkElement = Element;
/** Gets the return kind corresponding to specification `"ReturnValue"`. */
@@ -223,3 +236,22 @@ predicate interpretInputSpecific(string c, InterpretNode mid, InterpretNode n) {
a.getUnboundDeclaration() = mid.asElement()
)
}
bindingset[s]
private int parsePosition(string s) {
result = s.regexpCapture("([-0-9]+)", 1).toInt()
or
exists(int n1, int n2 |
s.regexpCapture("([-0-9]+)\\.\\.([0-9]+)", 1).toInt() = n1 and
s.regexpCapture("([-0-9]+)\\.\\.([0-9]+)", 2).toInt() = n2 and
result in [n1 .. n2]
)
}
/** Gets the argument position obtained by parsing `X` in `Parameter[X]`. */
bindingset[s]
ArgumentPosition parseParamBody(string s) { result.getPosition() = parsePosition(s) }
/** Gets the parameter position obtained by parsing `X` in `Argument[X]`. */
bindingset[s]
ParameterPosition parseArgBody(string s) { result.getPosition() = parsePosition(s) }

View File

@@ -8,24 +8,11 @@ import csharp
/**
* A callable that can be overridden or implemented.
*
* Unlike the class `Virtualizable`, this class only includes methods that
* can actually be overriden/implemented. Additionally, this class includes
* accessors whose declarations can actually be overridden/implemented.
* Unlike the class `Overridable`, this class only includes callables that
* can actually be overriden/implemented.
*/
class OverridableCallable extends Callable {
OverridableCallable() {
this.(Method).isOverridableOrImplementable() or
this.(Accessor).getDeclaration().isOverridableOrImplementable()
}
/** Gets a callable that immediately overrides this callable, if any. */
Callable getAnOverrider() { none() }
/**
* Gets a callable that immediately implements this interface callable,
* if any.
*/
Callable getAnImplementor(ValueOrRefType t) { none() }
class OverridableCallable extends Callable, Overridable {
OverridableCallable() { this.isOverridableOrImplementable() }
/**
* Gets a callable that immediately implements this interface member,
@@ -68,40 +55,6 @@ class OverridableCallable extends Callable {
)
}
/**
* Gets a callable that (transitively) implements this interface callable,
* if any. That is, either this interface callable is immediately implemented
* by the result, or the result overrides (transitively) another callable that
* immediately implements this interface callable.
*
* Note that this is generally *not* equivalent with
*
* ```ql
* result = getAnImplementor()
* or
* result = getAnImplementor().(OverridableCallable).getAnOverrider+()`
* ```
*
* as the example below illustrates:
*
* ```csharp
* interface I { void M(); }
*
* class A { public virtual void M() { } }
*
* class B : A, I { }
*
* class C : A { public override void M() }
*
* class D : B { public override void M() }
* ```
*
* If this callable is `I.M` then `A.M = getAnUltimateImplementor() ` and
* `D.M = getAnUltimateImplementor()`. However, it is *not* the case that
* `C.M = getAnUltimateImplementor()`, because `C` is not a sub type of `I`.
*/
Callable getAnUltimateImplementor() { none() }
/**
* Gets a callable that overrides (transitively) another callable that
* implements this interface callable, if any.
@@ -210,73 +163,10 @@ class OverridableCallable extends Callable {
}
/** An overridable method. */
class OverridableMethod extends Method, OverridableCallable {
override Method getAnOverrider() { result = Method.super.getAnOverrider() }
override Method getAnImplementor(ValueOrRefType t) { result = Method.super.getAnImplementor(t) }
override Method getAnUltimateImplementor() { result = Method.super.getAnUltimateImplementor() }
override Method getInherited(ValueOrRefType t) {
result = OverridableCallable.super.getInherited(t)
}
override Method getAnOverrider(ValueOrRefType t) {
result = OverridableCallable.super.getAnOverrider(t)
}
}
deprecated class OverridableMethod extends Method, OverridableCallable { }
/** An overridable accessor. */
class OverridableAccessor extends Accessor, OverridableCallable {
override Accessor getAnOverrider() { overrides(result, this) }
override Accessor getAnImplementor(ValueOrRefType t) {
exists(Virtualizable implementor, int kind |
this.getAnImplementorAux(t, implementor, kind) and
result.getDeclaration() = implementor and
getAccessorKind(result) = kind
)
}
// predicate folding to get proper join order
private predicate getAnImplementorAux(ValueOrRefType t, Virtualizable implementor, int kind) {
exists(Virtualizable implementee |
implementee = this.getDeclaration() and
kind = getAccessorKind(this) and
implementor = implementee.getAnImplementor(t)
)
}
override Accessor getAnUltimateImplementor() {
exists(Virtualizable implementor, int kind |
this.getAnUltimateImplementorAux(implementor, kind) and
result.getDeclaration() = implementor and
getAccessorKind(result) = kind
)
}
// predicate folding to get proper join order
private predicate getAnUltimateImplementorAux(Virtualizable implementor, int kind) {
exists(Virtualizable implementee |
implementee = this.getDeclaration() and
kind = getAccessorKind(this) and
implementor = implementee.getAnUltimateImplementor()
)
}
override Accessor getInherited(ValueOrRefType t) {
result = OverridableCallable.super.getInherited(t)
}
override Accessor getAnOverrider(ValueOrRefType t) {
result = OverridableCallable.super.getAnOverrider(t)
}
}
private int getAccessorKind(Accessor a) {
accessors(a, result, _, _, _) or
event_accessors(a, -result, _, _, _)
}
deprecated class OverridableAccessor extends Accessor, OverridableCallable { }
/** An unbound type. */
class UnboundDeclarationType extends Type {

View File

@@ -996,7 +996,7 @@ class QualifiableExpr extends Expr, @qualifiable_expr {
*/
predicate targetIsOverridableOrImplementable() {
not this.getQualifier() instanceof BaseAccess and
this.getQualifiedDeclaration().(Virtualizable).isOverridableOrImplementable()
this.getQualifiedDeclaration().(Overridable).isOverridableOrImplementable()
}
/** Holds if this expression has a conditional qualifier `?.` */

View File

@@ -3,7 +3,7 @@
*/
import csharp
private import semmle.code.csharp.dataflow.LibraryTypeDataFlow
private import semmle.code.csharp.dataflow.ExternalFlow
/** Definitions relating to the `Json.NET` package. */
module JsonNET {
@@ -31,15 +31,9 @@ module JsonNET {
}
/** The class `Newtonsoft.Json.JsonConvert`. */
class JsonConvertClass extends JsonClass, LibraryTypeDataFlow {
class JsonConvertClass extends JsonClass {
JsonConvertClass() { this.hasName("JsonConvert") }
/** Gets a `ToString` method. */
private Method getAToStringMethod() {
result = this.getAMethod("ToString") and
result.isStatic()
}
/** Gets a `Deserialize` method. */
Method getADeserializeMethod() {
result = this.getAMethod() and
@@ -51,39 +45,73 @@ module JsonNET {
result = this.getAMethod() and
result.getName().matches("Serialize%")
}
}
private Method getAPopulateMethod() {
result = this.getAMethod() and
result.getName().matches("Populate%")
}
override predicate callableFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
// ToString methods
c = this.getAToStringMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink instanceof CallableFlowSinkReturn
or
// Deserialize methods
c = this.getADeserializeMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink instanceof CallableFlowSinkReturn
or
// Serialize methods
c = this.getASerializeMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink instanceof CallableFlowSinkReturn
or
// Populate methods
c = this.getAPopulateMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink = any(CallableFlowSinkArg arg | arg.getArgumentIndex() = 1)
/** Data flow for `Newtonsoft.Json.JsonConvert`. */
private class JsonConvertClassFlowModelCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"Newtonsoft.Json;JsonConvert;false;DeserializeAnonymousType<>;(System.String,T);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeAnonymousType<>;(System.String,T,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject;(System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject;(System.String,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject;(System.String,System.Type);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject;(System.String,System.Type,Newtonsoft.Json.JsonConverter[]);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject;(System.String,System.Type,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject<>;(System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject<>;(System.String,Newtonsoft.Json.JsonConverter[]);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject<>;(System.String,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXNode;(System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXNode;(System.String,System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXNode;(System.String,System.String,System.Boolean);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXNode;(System.String,System.String,System.Boolean,System.Boolean);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXmlNode;(System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXmlNode;(System.String,System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXmlNode;(System.String,System.String,System.Boolean);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXmlNode;(System.String,System.String,System.Boolean,System.Boolean);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;PopulateObject;(System.String,System.Object);;Argument[0];Argument[1];taint",
"Newtonsoft.Json;JsonConvert;false;PopulateObject;(System.String,System.Object,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];Argument[1];taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object,Newtonsoft.Json.Formatting);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object,Newtonsoft.Json.Formatting,Newtonsoft.Json.JsonConverter[]);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object,Newtonsoft.Json.Formatting,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object,Newtonsoft.Json.JsonConverter[]);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object,System.Type,Newtonsoft.Json.Formatting,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object,System.Type,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeXNode;(System.Xml.Linq.XObject);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeXNode;(System.Xml.Linq.XObject,Newtonsoft.Json.Formatting);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeXNode;(System.Xml.Linq.XObject,Newtonsoft.Json.Formatting,System.Boolean);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeXmlNode;(System.Xml.XmlNode);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeXmlNode;(System.Xml.XmlNode,Newtonsoft.Json.Formatting);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeXmlNode;(System.Xml.XmlNode,Newtonsoft.Json.Formatting,System.Boolean);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Boolean);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Byte);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Char);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.DateTime);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.DateTime,Newtonsoft.Json.DateFormatHandling,Newtonsoft.Json.DateTimeZoneHandling);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.DateTimeOffset);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.DateTimeOffset,Newtonsoft.Json.DateFormatHandling);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Decimal);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Double);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Enum);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Guid);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Int16);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Int32);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Int64);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Object);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.SByte);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Single);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.String,System.Char);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.String,System.Char,Newtonsoft.Json.StringEscapeHandling);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.TimeSpan);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.UInt16);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.UInt32);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.UInt64);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Uri);;Argument[0];ReturnValue;taint",
]
}
}
@@ -137,7 +165,7 @@ module JsonNET {
}
/** The class `NewtonSoft.Json.JsonSerializer`. */
class JsonSerializerClass extends JsonClass, LibraryTypeDataFlow {
class JsonSerializerClass extends JsonClass {
JsonSerializerClass() { this.hasName("JsonSerializer") }
/** Gets the method for `JsonSerializer.Serialize`. */
@@ -145,22 +173,21 @@ module JsonNET {
/** Gets the method for `JsonSerializer.Deserialize`. */
Method getDeserializeMethod() { result = this.getAMethod("Deserialize") }
}
override predicate callableFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
// Serialize
c = this.getSerializeMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 1) and
sink = any(CallableFlowSinkArg arg | arg.getArgumentIndex() = 0)
or
// Deserialize
c = this.getDeserializeMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink instanceof CallableFlowSinkReturn
/** Data flow for `NewtonSoft.Json.JSonSerializer`. */
private class JsonSerializerClassFlowModelCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"Newtonsoft.Json;JsonSerializer;false;Deserialize;(Newtonsoft.Json.JsonReader);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonSerializer;false;Deserialize;(Newtonsoft.Json.JsonReader,System.Type);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonSerializer;false;Deserialize;(System.IO.TextReader,System.Type);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonSerializer;false;Serialize;(Newtonsoft.Json.JsonWriter,System.Object);;Argument[1];Argument[0];taint",
"Newtonsoft.Json;JsonSerializer;false;Serialize;(Newtonsoft.Json.JsonWriter,System.Object,System.Type);;Argument[1];Argument[0];taint",
"Newtonsoft.Json;JsonSerializer;false;Serialize;(System.IO.TextWriter,System.Object);;Argument[1];Argument[0];taint",
"Newtonsoft.Json;JsonSerializer;false;Serialize;(System.IO.TextWriter,System.Object,System.Type);;Argument[1];Argument[0];taint"
]
}
}
@@ -196,41 +223,23 @@ module JsonNET {
LinqClass() { this.getDeclaringNamespace() instanceof LinqNamespace }
}
/** The `NewtonSoft.Json.Linq.JObject` class. */
class JObjectClass extends LinqClass, LibraryTypeDataFlow {
JObjectClass() { this.hasName("JObject") }
override predicate callableFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
// ToString method
c = this.getAMethod("ToString") and
source instanceof CallableFlowSourceQualifier and
sink instanceof CallableFlowSinkReturn and
preservesValue = false
or
// Parse method
c = this.getParseMethod() and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink instanceof CallableFlowSinkReturn and
preservesValue = false
or
// operator string
c =
any(Operator op |
op.getDeclaringType() = this.getABaseType*() and op.getReturnType() instanceof StringType
) and
source.(CallableFlowSourceArg).getArgumentIndex() = 0 and
sink instanceof CallableFlowSinkReturn and
preservesValue = false
or
// SelectToken method
c = this.getSelectTokenMethod() and
source instanceof CallableFlowSourceQualifier and
sink instanceof CallableFlowSinkReturn and
preservesValue = false
/** Data flow for `Newtonsoft.Json.Linq.JToken`. */
private class JTokenClassFlowModelCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"Newtonsoft.Json.Linq;JToken;false;SelectToken;(System.String);;Argument[-1];ReturnValue;taint",
"Newtonsoft.Json.Linq;JToken;false;SelectToken;(System.String,Newtonsoft.Json.Linq.JsonSelectSettings);;Argument[-1];ReturnValue;taint",
"Newtonsoft.Json.Linq;JToken;false;SelectToken;(System.String,System.Boolean);;Argument[-1];ReturnValue;taint",
"Newtonsoft.Json.Linq;JToken;false;ToString;();;Argument[-1];ReturnValue;taint",
"Newtonsoft.Json.Linq;JToken;false;ToString;(Newtonsoft.Json.Formatting,Newtonsoft.Json.JsonConverter[]);;Argument[-1];ReturnValue;taint",
]
}
}
/** The `NewtonSoft.Json.Linq.JObject` class. */
class JObjectClass extends LinqClass {
JObjectClass() { this.hasName("JObject") }
/** Gets the `Parse` method. */
Method getParseMethod() { result = this.getAMethod("Parse") }
@@ -238,4 +247,15 @@ module JsonNET {
/** Gets the `SelectToken` method. */
Method getSelectTokenMethod() { result = this.getABaseType*().getAMethod("SelectToken") }
}
/** Data flow for `NewtonSoft.Json.Linq.JObject`. */
private class JObjectClassFlowModelCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"Newtonsoft.Json.Linq;JObject;false;Parse;(System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json.Linq;JObject;false;Parse;(System.String,Newtonsoft.Json.Linq.JsonLoadSettings);;Argument[0];ReturnValue;taint"
]
}
}
}

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