Compare commits

..

273 Commits

Author SHA1 Message Date
James Fletcher
413b4c6eb0 Merge pull request #11554 from github/siaramist/codeql-template
Update intro tutorial to include Codespaces CodeQL template
2023-01-04 09:56:36 +00:00
Siara
141bc41881 Update docs/codeql/writing-codeql-queries/introduction-to-ql.rst
Co-authored-by: James Fletcher <42464962+jf205@users.noreply.github.com>
2022-12-13 09:22:16 -08:00
Siara
44f91ad723 Update docs/codeql/reusables/codespaces-template-note.rst
Co-authored-by: James Fletcher <42464962+jf205@users.noreply.github.com>
2022-12-13 09:22:07 -08:00
Felicity Chapman
cbbce9b98a Update docs/codeql/writing-codeql-queries/introduction-to-ql.rst 2022-12-13 09:56:50 +00:00
Felicity Chapman
6aaaf4267b Update docs/codeql/writing-codeql-queries/introduction-to-ql.rst 2022-12-13 09:37:49 +00:00
SiaraMist
0518eda7ab Remove import tutorial 2022-12-12 17:46:03 -08:00
SiaraMist
dee66354cc Link to template reusable 2022-12-12 17:36:43 -08:00
Siara
094a9f4aa7 Edit reusable 2022-12-12 17:32:02 -08:00
Siara
028ab325f4 Update docs/codeql/reusables/codespaces-template-note.rst
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-12-12 17:28:39 -08:00
Siara
4aa92dfd88 Updates from review comments 2022-12-12 17:13:57 -08:00
Siara
169a465214 Update docs/codeql/writing-codeql-queries/introduction-to-ql.rst
Co-authored-by: James Fletcher <42464962+jf205@users.noreply.github.com>
2022-12-12 12:54:01 -08:00
SiaraMist
401a46d655 Update phrasing and link 2022-12-09 16:45:33 -08:00
Siara
9f75a768ea Update codespaces-template-note.rst 2022-12-09 15:59:27 -08:00
SiaraMist
ae4bc3eb09 Merge branch 'siaramist/codeql-template' of https://github.com/github/codeql into siaramist/codeql-template 2022-12-09 15:45:05 -08:00
SiaraMist
75fc9d0c6a Update reusable name 2022-12-09 15:43:30 -08:00
Siara
d1aacb7260 Add new line to end of reusable 2022-12-09 15:34:31 -08:00
SiaraMist
b4f7239f54 Updates from review 2022-12-09 15:27:04 -08:00
Siara
c1efb7f3f4 Update introduction-to-ql.rst 2022-12-08 16:12:59 -08:00
Siara
986c15cd08 Update introduction-to-ql.rst 2022-12-08 15:58:07 -08:00
Siara
dded684ad6 Update docs/codeql/writing-codeql-queries/introduction-to-ql.rst 2022-12-08 14:43:14 -08:00
Siara
7b6aa09646 Update introduction-to-ql.rst 2022-12-08 14:42:38 -08:00
Siara
b89dd3d8ac Merge branch 'codeql-cli-2.11.5' into siaramist/codeql-template 2022-12-08 14:07:58 -08:00
Siara
2ac736cd74 Update introduction-to-ql.rst 2022-12-08 14:07:39 -08:00
Nick Rolfe
23b02f4f27 Merge pull request #11544 from github/nickrolfe/update-query-docs
Docs: rewrite "defining the results of a query"
2022-12-05 17:14:56 +00:00
Nick Rolfe
731419fc80 Remove reference to query console
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-12-05 16:47:15 +00:00
Felicity Chapman
96476cb50d Merge pull request #11561 from github/felicitymay-lgtm-fixes
Remove one more outdated reference
2022-12-05 16:31:19 +00:00
Nick Rolfe
f31a7cf921 Apply suggestions from code review
Co-authored-by: James Fletcher <42464962+jf205@users.noreply.github.com>
2022-12-05 12:32:47 +00:00
Nick Rolfe
d893768726 Docs: rewrite "defining the results of a query"
The old guide was based on the code duplication library, which no longer
works, and used screenshots of LGTM, which is deprecated.
2022-12-05 10:18:32 +00:00
Felicity Chapman
6884db120a Remove another outdated reference 2022-12-05 09:56:28 +00:00
Felicity Chapman
90c6771dd1 Merge pull request #11502 from github/felicitymay-8441-detective
LGTM deprecation: Update QL detective tutorials
2022-12-05 09:40:00 +00:00
Felicity Chapman
dea9adbad4 Merge branch 'codeql-cli-2.11.5' into felicitymay-8441-detective 2022-12-02 23:48:23 +00:00
Felicity Chapman
2b24870a3d Merge pull request #11468 from github/felicitymay-8441-basic-query-2
LGTM deprecation: Update basic queries to use VS Code
2022-12-02 23:47:51 +00:00
SiaraMist
a1b6bfb270 Initial updates for CodeQL template 2022-12-02 13:07:25 -08:00
Felicity Chapman
5a57844dab Merge pull request #11503 from github/felicitymay-8441-next-batch
LGTM deprecation: a few more references missed in earlier PRs
2022-12-02 18:13:00 +00:00
Felicity Chapman
7aca35d52b Apply suggestions from code review 2022-12-02 13:09:38 +00:00
Felicity Chapman
42a438cdcb Apply suggestions from code review
Co-authored-by: Michael B. Gale <mbg@github.com>
2022-12-02 13:06:32 +00:00
Felicity Chapman
26908ea281 Update docs/codeql/codeql-language-guides/using-flow-labels-for-precise-data-flow-analysis.rst
Co-authored-by: Steve Guntrip <12534592+stevecat@users.noreply.github.com>
2022-12-02 09:36:10 +00:00
Chris Smowton
60e326b160 Merge pull request #11530 from github/release-prep/2.11.5
Release preparation for version 2.11.5
2022-12-01 21:53:38 +00:00
github-actions[bot]
31ab22e3a0 Release preparation for version 2.11.5 2022-12-01 20:05:14 +00:00
Felicity Chapman
6869ad48e4 Apply suggestions from code review
Co-authored-by: James Fletcher <42464962+jf205@users.noreply.github.com>
2022-12-01 17:40:24 +00:00
Felicity Chapman
38b8cf4fd4 Update docs/codeql/codeql-language-guides/basic-query-for-java-code.rst
Co-authored-by: Tony Torralba <atorralba@users.noreply.github.com>
2022-12-01 08:44:40 +00:00
Felicity Chapman
86e2333e67 Fix typo and try improving formatting 2022-11-30 15:53:19 +00:00
Felicity Chapman
3e1d49ad80 First draft update tutorials 2022-11-30 15:38:58 +00:00
Felicity Chapman
9eafee365f Some updates missed in earlier PRs 2022-11-30 12:30:28 +00:00
Felicity Chapman
6dee013baa Merge branch 'rc/3.8' into felicitymay-8441-basic-query-2 2022-11-30 11:39:20 +00:00
Felicity Chapman
0d7b27d4e4 A few fixes 2022-11-29 15:52:29 +00:00
Felicity Chapman
1142b77f8d Update articles for other languages 2022-11-29 15:09:15 +00:00
Felicity Chapman
0def31a2ce Update Go article 2022-11-29 12:37:10 +00:00
Felicity Chapman
c66569bd43 Generalize cpp changes and apply to csharp 2022-11-29 11:50:26 +00:00
Felicity Chapman
5898615f5a Merge pull request #11420 from github/felicitymay-8441-query-guides-java
LGTM deprecation: updates to CodeQL for Java articles
2022-11-29 09:23:21 +00:00
Felicity Chapman
1dc6640bc1 Remove superfluous content
(cherry picked from commit 5d03892943)
2022-11-29 09:19:21 +00:00
Felicity Chapman
229c3e6e8f Update for James' review comments
(cherry picked from commit 174fbf672f)
2022-11-29 09:19:21 +00:00
Felicity Chapman
97db2c91f1 First draft update basic query to use VS Code
(cherry picked from commit 3e0702f904)
2022-11-29 09:19:21 +00:00
Felicity Chapman
9780990836 Merge pull request #11433 from github/8441-general-changes
LGTM deprecation: miscellaneous changes
2022-11-29 09:06:31 +00:00
Felicity Chapman
434c5ea188 Merge pull request #11422 from github/felicitymay-8441-query-guides-python
LGTM deprecation: updates to CodeQL for Python articles
2022-11-29 09:04:48 +00:00
Felicity Chapman
114d337210 Merge pull request #11421 from github/felicitymay-8441-query-guides-c
LGTM deprecation: updates to CodeQL for C/C++ articles
2022-11-29 09:04:31 +00:00
Felicity Chapman
0624324962 Merge branch 'rc/3.8' into felicitymay-8441-query-guides-java 2022-11-29 09:03:32 +00:00
Erik Krogh Kristensen
ae40b0aba2 Merge pull request #11419 from github/felicitymay-8441-query-guides-javascript
LGTM deprecation: updates to CodeQL for JavaScript articles
2022-11-28 21:57:37 +01:00
Felicity Chapman
59b6d657cc Apply suggestions from code review
Co-authored-by: hubwriter <hubwriter@github.com>
2022-11-28 15:45:05 +01:00
Felicity Chapman
7e5a9fbe2e Update note for review comments 2022-11-28 15:41:39 +01:00
Felicity Chapman
179941daab First set of updates for JavaScript articles 2022-11-28 15:41:39 +01:00
Felicity Chapman
33ae086861 Apply suggestions from code review
Co-authored-by: Tony Torralba <atorralba@users.noreply.github.com>
2022-11-28 15:38:03 +01:00
Felicity Chapman
d6ae5c898a Respond to review feedback 2022-11-28 15:38:03 +01:00
Felicity Chapman
a9b6a12317 Updates for Java articles 2022-11-28 15:38:03 +01:00
Felicity Chapman
85961f5dce Update docs/codeql/codeql-language-guides/functions-in-cpp.rst 2022-11-28 15:36:05 +01:00
Felicity Chapman
8ec06d45e0 Replace LGTM description with VS Code 2022-11-28 15:36:05 +01:00
Felicity Chapman
b22ccc114e Minor changes to Go and Ruby article 2022-11-28 15:36:05 +01:00
Felicity Chapman
0ac0277639 Minor change to C# article 2022-11-28 15:36:05 +01:00
Felicity Chapman
a407f0a4ac Update main C/C++ articles 2022-11-28 15:36:04 +01:00
Felicity Chapman
da4c178534 Update main Python articles 2022-11-28 15:34:12 +01:00
Felicity Chapman
c1e6d4c82a Update .github/ISSUE_TEMPLATE/ql---general.md 2022-11-28 15:26:24 +01:00
Felicity Chapman
c451fa8ad4 Update cpp/ql/src/Likely Bugs/RedundantNullCheckSimple.ql
Co-authored-by: Taus <tausbn@github.com>
2022-11-28 15:26:24 +01:00
Felicity Chapman
ea127c3d99 A few more references 2022-11-28 15:26:24 +01:00
Felicity Chapman
b5f849463b Update QL library references 2022-11-28 15:26:24 +01:00
Felicity Chapman
c06db6b67c Remove LGTM support info 2022-11-28 15:26:22 +01:00
Felicity Chapman
fb0959bcea Update QL reference 2022-11-28 15:25:38 +01:00
Felicity Chapman
5f835da838 Update HTML comment in query 2022-11-28 15:25:38 +01:00
Felicity Chapman
36a6ccba8b Remove reference in template 2022-11-28 15:25:38 +01:00
Felicity Chapman
a76d47681d Replace references in Qhelp files 2022-11-28 15:25:37 +01:00
Edoardo Pirovano
8eeba92a47 Merge pull request #11415 from github/edoardo/mergeback-2.11.4
Merge `codeql-cli-2.11.4` into `rc/3.8`
2022-11-24 14:42:36 +00:00
Ben Ahmady
7f5df4fc0e Merge pull request #11384 from github/subatoi/codeql-cli-2.11.4
Adds Kotlin (beta) content
2022-11-24 11:33:46 +00:00
Ben Ahmady
42259ef8d1 Update docs/codeql/reusables/kotlin-java-differences.rst 2022-11-24 10:10:42 +00:00
Ben Ahmady
357c823b92 Changes after feedback 2022-11-23 16:59:52 +00:00
Ian Lynagh
d03817ce2d Merge pull request #11399 from igfoo/igfoo/kotlin-basic
Java/Kotlin: Make the basic query in docs work for both languages
2022-11-23 16:01:04 +00:00
Ian Lynagh
277b5b483d Java/Kotlin docs: Tweak text 2022-11-23 15:51:40 +00:00
Ian Lynagh
950c4c811c Java/Kotlin: Make the basic query in docs work for both languages 2022-11-23 15:18:29 +00:00
Ian Lynagh
9ee36215bd Java: Fix basic query in docs 2022-11-23 15:14:46 +00:00
Ben Ahmady
ee0811df26 Update docs/codeql/codeql-language-guides/codeql-for-java.rst 2022-11-23 15:13:40 +00:00
Ben Ahmady
f9215ec5ca Update docs/codeql/reusables/kotlin-java-differences.rst
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-11-23 15:10:24 +00:00
Ben Ahmady
72999c7af1 Update docs/codeql/reusables/kotlin-java-differences.rst
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-11-23 15:10:14 +00:00
Ben Ahmady
3c3442d8f0 Update docs/codeql/reusables/kotlin-java-differences.rst
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-11-23 15:09:58 +00:00
Ben Ahmady
dcd082e955 Possible build fix, else needs new parameter 2022-11-23 12:48:47 +00:00
Ben Ahmady
40c2b3c43b Merge branch 'codeql-cli-2.11.4' into subatoi/codeql-cli-2.11.4 2022-11-23 10:18:46 +00:00
Ben Ahmady
093ff4061d Update docs/codeql/reusables/kotlin-java-differences.rst
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-11-23 10:08:45 +00:00
Ben Ahmady
7644ecad52 Update docs/codeql/reusables/kotlin-java-differences.rst
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-11-23 10:08:29 +00:00
Ben Ahmady
0a91ee1019 Update docs/codeql/codeql-language-guides/abstract-syntax-tree-classes-for-working-with-java-programs.rst 2022-11-23 10:08:20 +00:00
Ben Ahmady
df7f0cf9a9 Update docs/codeql/codeql-language-guides/analyzing-data-flow-in-java.rst 2022-11-23 10:08:10 +00:00
Ben Ahmady
c06b8a68e5 Update docs/codeql/reusables/kotlin-java-differences.rst
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-11-23 10:08:00 +00:00
Ben Ahmady
c663da5be6 Update docs/codeql/reusables/kotlin-java-differences.rst
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-11-23 10:07:03 +00:00
Ben Ahmady
4bd7e24b5f Update docs/codeql/reusables/kotlin-java-differences.rst
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-11-23 10:06:57 +00:00
Ben Ahmady
605c7113a2 Update docs/codeql/reusables/kotlin-java-differences.rst
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-11-23 10:06:48 +00:00
Ben Ahmady
e2240abc78 Update docs/codeql/codeql-language-guides/codeql-for-java.rst
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2022-11-23 10:06:34 +00:00
Paolo Tranquilli
545c2f67e9 Merge pull request #11382 from github/alexdenisov/swift-relax-file-archiving
Swift: do not abort if cannot archive a source file
2022-11-23 06:56:26 +01:00
Paolo Tranquilli
d345cec339 Merge pull request #11381 from github/alexdenisov/swift-fix-remapping-regression
Swift: fix remapping bug
2022-11-23 06:56:05 +01:00
Ben Ahmady
24c413fbf9 Adds Kotlin (beta) content 2022-11-22 18:33:24 +00:00
Alex Denisov
8f02463411 Swift: fix remapping bug
This issue has slipped during a recent refactoring:
https://github.com/github/codeql/pull/10987/files#diff-c5ab26a06a93c4507a834859a6a56878d5bfe16c4d7cbac4afc4f081d46f461aL63-R64
2022-11-22 17:25:07 +01:00
Alex Denisov
a2ac1384cb Swift: do not abort if cannot archive a source file 2022-11-22 17:18:40 +01:00
Chris Smowton
f589ba8b9c Merge pull request #11327 from github/post-release-prep/codeql-cli-2.11.4
Post-release preparation for codeql-cli-2.11.4
2022-11-18 14:42:51 +00:00
github-actions[bot]
5b14ebf22a Post-release preparation for codeql-cli-2.11.4 2022-11-18 11:26:00 +00:00
Chris Smowton
29c47ad515 Merge pull request #11320 from github/release-prep/2.11.4
Release preparation for version 2.11.4
2022-11-17 18:57:14 +00:00
Chris Smowton
0deb2d4c5f Copyedit Python release notes 2022-11-17 17:03:09 +00:00
Chris Smowton
63fcbb5969 Copyedit Python release notes 2022-11-17 17:02:55 +00:00
Chris Smowton
0219c2b02b Copyedit Javascript changelog 2022-11-17 17:02:01 +00:00
Chris Smowton
80b2f0d3cd Coopyedit Javascript changelog 2022-11-17 17:01:43 +00:00
Chris Smowton
d45c35a02e Copyedit the Java src qlpack 0.4.4 release nnotes 2022-11-17 16:57:08 +00:00
Chris Smowton
47f07d83b8 Copyedit Java src qlpack changelog 2022-11-17 16:56:39 +00:00
Chris Smowton
e13eb79f5b Java: edit 0.4.4 release notes to match the changelog 2022-11-17 16:55:26 +00:00
Chris Smowton
2bd151ba9c Copyedit Java changelog 2022-11-17 16:54:33 +00:00
Chris Smowton
7c74350d5e Copyedit Java changelog 2022-11-17 16:51:21 +00:00
github-actions[bot]
e105c13e77 Release preparation for version 2.11.4 2022-11-17 16:40:45 +00:00
Chris Smowton
254a5b0928 Merge pull request #11293 from smowton/smowton/admin/exclude-kotlin-metadata-annotation
Java: Remove no-longer-needed expected diagnostics
2022-11-17 11:50:21 +00:00
Tom Hvitved
bbcef98e06 Merge pull request #11317 from hvitved/cpp/update-autobuilder-nuget-packages
C++: Update auto-builder nuget packages
2022-11-17 12:38:26 +01:00
Tamás Vajk
d8b5a04f97 Merge pull request #11291 from tamasvajk/kotlin-confusing-overload
Kotlin: Add test case for confusing overloading query
2022-11-17 11:11:33 +01:00
Tamás Vajk
c92989ca04 Merge pull request #11289 from tamasvajk/kotlin-empty-block
Kotlin: Exclude .kt files from empty block query
2022-11-17 11:11:25 +01:00
Chris Smowton
659f86cecf Merge pull request #11310 from tamasvajk/kotlin-dead-code
Kotlin: Exclude .kt files from dead code queries
2022-11-17 10:10:51 +00:00
Chris Smowton
95fdea8b77 Merge pull request #11308 from tamasvajk/kotlin-non-serializable-field
Kotlin: Exclude .kt files from non serializable field query
2022-11-17 10:10:05 +00:00
Chris Smowton
11188304a7 Merge pull request #11306 from tamasvajk/kotlin-equals-missing
Kotlin: Exclude .kt files from missing `instanceof` in `equals` query
2022-11-17 10:09:35 +00:00
Tom Hvitved
780297152c C#: Downgrade Microsoft.Build nuget package
17.4.0 does not officially support .NET 6 (it supports .NET 7), so downgrade
to avoid warnings.
2022-11-17 11:00:25 +01:00
Tom Hvitved
5ab77600b8 C++: Update auto-builder nuget packages 2022-11-17 10:44:23 +01:00
Erik Krogh Kristensen
45d4318e0e Merge pull request #11272 from erik-krogh/clean-cache
CI: clean up the cache when compiling on main
2022-11-17 10:37:08 +01:00
Erik Krogh Kristensen
ba894e21e8 Merge pull request #11146 from mbaluda-org/main
JS: Improved Hapi support
2022-11-17 10:22:48 +01:00
Mauro Baluda
a7dc29bad4 Merge branch 'main' into main 2022-11-16 23:53:16 +01:00
Mauro Baluda
49f476d3b4 Update javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2022-11-16 23:53:07 +01:00
Harry Maclean
a6f6936719 Merge pull request #11058 from hmac/actioncontroller-logger
Ruby: Model various ActionController methods
2022-11-17 08:21:00 +13:00
Tom Hvitved
baaafadeb0 Merge pull request #11266 from hvitved/csharp/update-nuget-packages
C#: Update all nuget packages
2022-11-16 19:53:45 +01:00
Tamás Vajk
b70a9d172b Merge pull request #11304 from tamasvajk/kotlin-mut-dep
Kotlin: Exclude .kt files from mutual dependency query
2022-11-16 17:02:46 +01:00
Tamás Vajk
ae38d5d8b7 Merge pull request #11303 from tamasvajk/kotlin-one-stmt-line
Kotlin: Exclude .kt files from one stmt in line query
2022-11-16 17:02:35 +01:00
Mathias Vorreiter Pedersen
2796c46598 Merge pull request #11292 from github/redsun82/swift-remove-ipa-from-dbscheme-cpp
Swift: remove synthesized classes from the dbscheme
2022-11-16 16:00:58 +00:00
Paolo Tranquilli
1c69a1f012 Swift: fix typo in docstring 2022-11-16 16:36:48 +01:00
Paolo Tranquilli
27df44f5ad Swift: replace empty IpaInfo() with a clearer True value 2022-11-16 16:35:17 +01:00
Joe Farebrother
d6c5132f39 Merge pull request #10684 from joefarebrother/android-keyboard-cache
Java: Add query for Sensitive Keyboard Cache
2022-11-16 15:27:44 +00:00
Tamás Vajk
dfc72edba2 Merge pull request #11302 from tamasvajk/kotlin-ignored-return
Kotlin: Exclude .kt files from ignored return value query
2022-11-16 16:23:58 +01:00
Tamás Vajk
ad7c0f9ebc Merge pull request #11301 from tamasvajk/kotlin-naming-ref-type
Kotlin: Exclude .kt files from misnamed reftype query
2022-11-16 16:22:40 +01:00
Tamás Vajk
a3ff83595a Merge pull request #11300 from tamasvajk/kotlin-useless-param-2
Kotlin: Exclude .kt files from useless parameter query
2022-11-16 16:22:27 +01:00
Tamás Vajk
b4b8649fd6 Merge pull request #11299 from tamasvajk/kotlin-nested-serializable
Kotlin: Exclude .kt files from serializable inner class query
2022-11-16 16:22:13 +01:00
Tamas Vajk
8b6bf910ba Kotlin: Exclude .kt files from dead code queries 2022-11-16 16:20:09 +01:00
Tamas Vajk
983851fc60 Kotlin: Add FP test case for dead code queries 2022-11-16 16:18:37 +01:00
erik-krogh
e4b0d8dbf3 simplify the copy-logic, because cp -r actually creates the folders 2022-11-16 16:10:41 +01:00
Rasmus Wriedt Larsen
3894fad54d Merge pull request #11307 from github/RasmusWL/ql-style-no-return
ql-style-guide: Remove use of `return`
2022-11-16 15:39:35 +01:00
Tamas Vajk
7d9ce53080 Kotlin: Exclude .kt files from non serializable field query 2022-11-16 15:30:25 +01:00
Tamas Vajk
a9023d06d0 Kotlin: Add FP test case for non serializable field query 2022-11-16 15:29:24 +01:00
Rasmus Wriedt Larsen
9f2d89c903 Update ql-style-guide.md
Our [QLDoc style guide](https://github.com/github/codeql/blob/main/docs/qldoc-style-guide.md#predicates-with-result) says that we should avoid any use of `return`, so it would be smart to also do so in our own style guide for predicate names 😊
2022-11-16 15:27:38 +01:00
Tamas Vajk
fc614ad4d0 Kotlin: Exclude .kt files from missing instanceof in equals query 2022-11-16 15:24:47 +01:00
Tamas Vajk
b6978128b1 Exclude .kt files from mutual dependency query 2022-11-16 15:16:51 +01:00
Tamas Vajk
63e9ae3b93 Kotlin: Add FP test case for mutual dependency query 2022-11-16 15:16:18 +01:00
Tom Hvitved
67b6a82cf1 Merge pull request #11198 from hvitved/ssa/expose-phi-reads
SSA: Expose phi-read nodes
2022-11-16 15:11:58 +01:00
Tamas Vajk
c9241cc933 Exclude .kt files from one stmt in line query 2022-11-16 15:11:38 +01:00
Tamas Vajk
0d70b5c776 Kotlin: Add FP test case for one stmt in line query 2022-11-16 15:10:38 +01:00
Tamas Vajk
c42663723f Exclude .kt files from ignored return value query 2022-11-16 15:05:29 +01:00
Tamas Vajk
5f6f72ba8e Kotlin: Add FP test case for ignored return value query 2022-11-16 15:05:07 +01:00
Tamas Vajk
c1be93a34c Exclude .kt files from misnamed reftype query 2022-11-16 14:59:20 +01:00
Tamas Vajk
e547be5e9a Kotlin: Add FP test case for misnamed reftype query 2022-11-16 14:58:36 +01:00
Tamas Vajk
48c37a2c0f Exclude .kt files from useless parameter query 2022-11-16 14:51:49 +01:00
Tamas Vajk
35078738bc Kotlin: Add FP test case for useless parameter query 2022-11-16 14:51:21 +01:00
Chris Smowton
d6a395ba37 Remove non-longer-needed expected diagnostics 2022-11-16 13:49:59 +00:00
Chris Smowton
6c0bef7e6e Merge pull request #11297 from erik-krogh/add-stats
JS: add stats for @satisfies_expr
2022-11-16 13:49:25 +00:00
Tamas Vajk
7a0e248096 Exclude .kt files from serializable inner class query 2022-11-16 14:46:01 +01:00
Tamas Vajk
782c82a2d3 Kotlin: Add test case for non serializable inner class query 2022-11-16 14:44:48 +01:00
Tom Hvitved
54a6f066b3 Address review comment 2022-11-16 14:02:21 +01:00
Tamás Vajk
468a6f2a70 Merge pull request #11290 from tamasvajk/kotlin-autoboxing
Kotlin: Exclude .kt files from autoboxing query
2022-11-16 13:56:29 +01:00
Tamás Vajk
266a0874b5 Merge pull request #11284 from tamasvajk/kotlin-complex-bool-expr
Kotlin: Exclude .kt files from `java/complex-boolean-expression`
2022-11-16 13:55:30 +01:00
Tamás Vajk
91b7798be8 Merge pull request #11286 from tamasvajk/kotlin-resource-leak
Kotlin: Exclude .kt files from resource leak queries
2022-11-16 13:55:12 +01:00
erik-krogh
76c6943159 add stats for @satisfies_expr 2022-11-16 13:48:41 +01:00
Tom Hvitved
67e8ec1a5f Swift: Update expected test output 2022-11-16 13:36:03 +01:00
Arthur Baars
bfb0ca7968 Merge pull request #11276 from aibaars/false-positive
CodeQL: add 'False positive' issue template
2022-11-16 13:00:14 +01:00
Arthur Baars
f0c3d039a1 Merge pull request #11227 from github/sj/remove-LGTM-issue-template
Remove issue template for LGTM.com false positive reports
2022-11-16 12:59:59 +01:00
Anders Schack-Mulligen
94bca4399a Merge pull request #11183 from aschackmull/dataflow/groupflow
Dataflow: Introduce support for src/sink grouping in path results.
2022-11-16 12:59:01 +01:00
Erik Krogh Kristensen
7d4ea47611 Merge pull request #10855 from erik-krogh/formatTaint
Ruby: taint-steps for printf calls - and add a `AdditionalTaintStep` class
2022-11-16 12:08:45 +01:00
Mauro Baluda
8bf0bbb715 code generalization
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2022-11-16 12:06:23 +01:00
Mauro Baluda
798b03f29d code generalization
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2022-11-16 12:06:07 +01:00
Paolo Tranquilli
bafb9ae020 Swift: add upgrade/downgrade scripts 2022-11-16 12:00:26 +01:00
Tamas Vajk
55dc929a1f Kotlin: Add test case for confusing overloading query 2022-11-16 11:57:05 +01:00
Joe Farebrother
cc960377ac Apply suggestion from docs review
Co-authored-by: Sam Browning <106113886+sabrowning1@users.noreply.github.com>
2022-11-16 10:54:14 +00:00
Joe Farebrother
255123cbf9 Apply suggestions from docs review
Co-authored-by: Sam Browning <106113886+sabrowning1@users.noreply.github.com>
2022-11-16 10:54:14 +00:00
Joe Farebrother
7ae41ff165 Invert the xml logic to be consistent with the dataflow logic 2022-11-16 10:54:14 +00:00
Joe Farebrother
6d465aaf52 Apply code review suggestions 2022-11-16 10:54:14 +00:00
Joe Farebrother
63f715e650 fix implicit this 2022-11-16 10:54:14 +00:00
Joe Farebrother
dd4e1d0ac3 Add tests and fix issues 2022-11-16 10:54:14 +00:00
Joe Farebrother
10a3b3bd14 Cover cases in which input type is set via code 2022-11-16 10:54:14 +00:00
Joe Farebrother
359d703ded More precise layout xml handling 2022-11-16 10:54:13 +00:00
Joe Farebrother
f48b57c95a Apply review suggestions 2022-11-16 10:54:13 +00:00
Joe Farebrother
e6dd3673a1 Fix qldoc 2022-11-16 10:54:13 +00:00
Joe Farebrother
b4216767ad Add change note 2022-11-16 10:54:13 +00:00
Joe Farebrother
775a5507a6 Add security severity 2022-11-16 10:54:13 +00:00
Joe Farebrother
c085c1f3ad Fix typos 2022-11-16 10:54:13 +00:00
Joe Farebrother
0bce1894ae Remove redundant import 2022-11-16 10:54:13 +00:00
Joe Farebrother
92190e5095 Add docs 2022-11-16 10:54:13 +00:00
Joe Farebrother
706858e211 Add test cases; fix the regex used 2022-11-16 10:54:13 +00:00
Joe Farebrother
85fe226256 Add sensitive keyboard cache query 2022-11-16 10:54:13 +00:00
Tamas Vajk
3d21f89f1d Exclude .kt files from autoboxing query 2022-11-16 11:52:17 +01:00
Tamas Vajk
0d9e28012e Kotlin: Add FP test cases for autoboxing query 2022-11-16 11:51:36 +01:00
Tamas Vajk
3d11e5bb32 Exclude .kt files from empty block query 2022-11-16 11:47:35 +01:00
Tamas Vajk
c91e20c6b5 Kotlin: Add FP test cases for empty blocks 2022-11-16 11:47:07 +01:00
Paolo Tranquilli
a3d33e27e2 Swift: ignore IPA classes in dbscheme 2022-11-16 11:39:10 +01:00
Joe Farebrother
3ebb7cfa1b Merge pull request #11269 from joefarebrother/stub-gen-invalid-ids
Java: Stub generator: Exclude invalid identifiers from generated stubs
2022-11-16 10:26:22 +00:00
Paolo Tranquilli
88a0c4053b Swift: move hierarchy IPA logic to schema.py 2022-11-16 11:14:17 +01:00
Mauro Baluda
784475dd66 Merge branch 'main' into main 2022-11-16 11:06:27 +01:00
Mauro Baluda
84cb59b942 Create 2022-11-08-hapi-glue.md 2022-11-16 11:05:23 +01:00
AlexDenisov
0c14759e86 Merge pull request #11285 from github/redsun82/swift-fix-generated-artifact
Swift: fix path of generated C++ files artifact
2022-11-16 10:47:01 +01:00
Paolo Tranquilli
6d1421a6f9 Swift: fix workflow mention in CODEOWNERS 2022-11-16 10:04:19 +01:00
Tamas Vajk
307d2d5dc1 Exclude .kt files from resource leak queries 2022-11-16 09:52:39 +01:00
Tamas Vajk
acab8e8632 Kotlin: Add FP test cases for resource leaks 2022-11-16 09:52:13 +01:00
Paolo Tranquilli
d4f3e38062 Swift: fix path of generated C++ files artifact 2022-11-16 09:49:57 +01:00
Tamas Vajk
ac85d2eb3e Exclude .kt files from java/complex-boolean-expression 2022-11-16 09:38:42 +01:00
Tamas Vajk
de833d620e Kotlin: Add FP test case for unnecessarily complex bool expression 2022-11-16 09:35:18 +01:00
Harry Maclean
ed3270fb04 Ruby: Update for upstream changes 2022-11-16 14:06:32 +13:00
Harry Maclean
2e2fcd49bf Ruby: Consider Object#inspect a log sanitizer
The behaviour of `Object#inspect` depends on whether it has been
overridden by a subclass, but it will typically produce output on a
single line. Calling `inspect` on a String will replace newlines with
`\n`, which is then safe for interpolation into a log line.
2022-11-16 13:46:51 +13:00
Harry Maclean
762ebad66e Ruby: Add change note 2022-11-16 13:46:51 +13:00
Harry Maclean
d0521f15f1 Ruby: Update tests 2022-11-16 13:46:51 +13:00
Harry Maclean
d2c0250b41 Ruby: Model ActionDispatch::Request#body_stream 2022-11-16 13:46:51 +13:00
Harry Maclean
9f357837fa Ruby: Model send_data as an HTTP response 2022-11-16 13:46:51 +13:00
Harry Maclean
5cfc494e16 Ruby: Test render inside redirect_to
This test shows that we correctly identify redirect_to and render calls
inside respond_to blocks.
2022-11-16 13:46:51 +13:00
Harry Maclean
155b64d3fc Ruby: Add test for render calls 2022-11-16 13:46:51 +13:00
Harry Maclean
b7e14311be Ruby: Model ActionController logger 2022-11-16 13:46:50 +13:00
Harry Maclean
27681ac987 Ruby: Move ActionController tests to own directory 2022-11-16 13:46:49 +13:00
Erik Krogh Kristensen
c70f3d35d0 Merge pull request #11256 from erik-krogh/ts49
JS: Add support for TypeScript 4.9
2022-11-16 01:05:40 +01:00
Mauro Baluda
ec04f0c88f hapi/glue tests 2022-11-15 23:45:27 +01:00
erik-krogh
8cb68b79c1 bump extractor version 2022-11-15 22:09:09 +01:00
erik-krogh
b0b5761a8c update TS from 4.9.2-rc to 4.9.3 2022-11-15 22:08:54 +01:00
erik-krogh
364336e22a add downgrade script 2022-11-15 22:07:25 +01:00
erik-krogh
1f90f7dd4d add upgrade script 2022-11-15 22:07:25 +01:00
erik-krogh
d4c6f873af add test for auto-accessors 2022-11-15 22:07:25 +01:00
erik-krogh
65567fa1ce add test for the more precise type-narrowing with the in operator 2022-11-15 22:07:25 +01:00
erik-krogh
e98d1df5f4 add dataflow support 2022-11-15 22:07:25 +01:00
erik-krogh
a8973c1147 add test for dataflow 2022-11-15 22:07:24 +01:00
erik-krogh
75ef5b1b0b add support for satisfies-expressions 2022-11-15 22:07:24 +01:00
erik-krogh
30c66303ba initial skeleton for TypeScript 4.9 2022-11-15 22:07:24 +01:00
Arthur Baars
0ce4500b48 Apply suggestions from code review
Co-authored-by: Pierre <turbo@github.com>
2022-11-15 18:20:28 +01:00
Arthur Baars
da7788dd64 CodeQL: add 'False positive' issue template 2022-11-15 16:53:53 +01:00
Mauro Baluda
8109a7b67a Update javascript/ql/lib/semmle/javascript/frameworks/Hapi.qll
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2022-11-15 16:27:21 +01:00
Mauro Baluda
e5e3bb3705 Generalize the server definition in plugin registration 2022-11-15 16:27:14 +01:00
Mauro Baluda
563a56af9d Update Hapi.qll 2022-11-15 15:46:34 +01:00
erik-krogh
65c1e239eb clean up the cache when compiling on main 2022-11-15 14:49:06 +01:00
Joe Farebrother
8d9b106be1 Exclude invalid identifiers from generated stubs 2022-11-15 11:19:40 +00:00
Tom Hvitved
67f31ffdf0 Ruby: Add tests for phi reads 2022-11-15 11:45:32 +01:00
Tom Hvitved
bd78e73131 C#: Add tests for phi reads 2022-11-15 11:45:32 +01:00
Tom Hvitved
81a1fa167a SSA: Expose phi-reads 2022-11-15 11:45:32 +01:00
Tom Hvitved
32f60fd112 Ruby: Add more local flow tests for use-use flow 2022-11-15 11:45:31 +01:00
Tom Hvitved
dc2cd994d4 C#: Update expected test output 2022-11-15 11:22:48 +01:00
Tom Hvitved
a749212707 C#: Handle op_Checked* operators in the extractor 2022-11-15 11:22:19 +01:00
Tom Hvitved
eda028721e C#: Update all nuget packages 2022-11-15 09:19:33 +01:00
Mauro Baluda
3260c81397 Merge branch 'github:main' into main 2022-11-14 22:59:06 +01:00
Mauro Baluda
5ea03b1ded Update Hapi.qll
Add `server` definitions in plugin registration and plugin dependency declaration
2022-11-14 22:56:06 +01:00
Bas van Schaik
8147d2048e Remove issue template for LGTM.com false positive reports 2022-11-11 10:36:26 +00:00
Mauro Baluda
25ac3499c2 Merge branch 'github:main' into main 2022-11-11 11:20:01 +01:00
Mauro Baluda
53f1985e77 Merge branch 'github:main' into main 2022-11-10 13:27:20 +01:00
Mauro Baluda
ee02265ac2 Add property params to RequestInputAccess 2022-11-10 12:24:39 +01:00
Anders Schack-Mulligen
b3b7711149 Dataflow: Sync. 2022-11-09 14:23:15 +01:00
Anders Schack-Mulligen
ade83b3cfe Dataflow: Introduce support for src/sink grouping in path results. 2022-11-09 14:22:24 +01:00
Mauro Baluda
8e546e8496 Add req.url.origin to RequestInputAccess 2022-11-08 16:14:10 +01:00
Mauro Baluda
8b33e6d175 Improved Hapi support
- server defined by Glue
2022-11-07 16:29:44 +01:00
erik-krogh
6bc12e8f2b Merge branch 'main' into formatTaint 2022-11-02 13:39:30 +01:00
erik-krogh
33cca29a8e drop down to the CFG instead of the AST to better support de-sugaring 2022-11-02 11:23:01 +01:00
erik-krogh
aafef382dc refactor StringPercentCall#getFormatArgument 2022-10-24 18:57:24 +02:00
erik-krogh
c13e8e4f48 Merge branch 'main' into formatTaint 2022-10-20 10:46:16 +02:00
erik-krogh
bb4bc55c6a update expected output 2022-10-17 15:52:21 +02:00
erik-krogh
f09e3bd3ac add String#% as a printf like call 2022-10-17 13:51:43 +02:00
erik-krogh
d4919d04ba add a taint-step for format-calls 2022-10-17 13:16:38 +02:00
erik-krogh
f222cc1f3e refactor the existing taint-step for string interpolation into StringFormatters.qll 2022-10-17 13:16:38 +02:00
erik-krogh
6de1abcb0e add a returnsFormatted predicate to the printf model, similar to the JS implementation 2022-10-17 13:16:38 +02:00
erik-krogh
a2b924bbdf move model of printf style calls to StringFormatters.qll 2022-10-17 13:16:34 +02:00
erik-krogh
dbf2673a91 add returnsFormatted predicate to PrintfStyleCall (similar to JS) 2022-10-17 12:15:31 +02:00
erik-krogh
46627a737e add an AdditionalTaintStep class for Ruby 2022-10-17 12:15:30 +02:00
491 changed files with 75351 additions and 3204 deletions

View File

@@ -1,24 +0,0 @@
---
name: LGTM.com - false positive
about: Tell us about an alert that shouldn't be reported
title: LGTM.com - false positive
labels: false-positive
assignees: ''
---
**Description of the false positive**
<!-- Please explain briefly why you think it shouldn't be included. -->
**URL to the alert on the project page on LGTM.com**
<!--
1. Open the project on LGTM.com.
For example, https://lgtm.com/projects/g/pallets/click/.
2. Switch to the `Alerts` tab. For example, https://lgtm.com/projects/g/pallets/click/alerts/.
3. Scroll to the alert that you would like to report.
4. Click on the right most icon `View this alert within the complete file`.
5. A new browser tab opens. Copy and paste the page URL here.
For example, https://lgtm.com/projects/g/pallets/click/snapshot/719fb7d8322b0767cdd1e5903ba3eb3233ba8dd5/files/click/_winconsole.py#xa08d213ab3289f87:1.
-->

View File

@@ -10,5 +10,5 @@ assignees: ''
**Description of the issue**
<!-- Please explain briefly what is the problem.
If it is about an LGTM project, please include its URL.-->
If it is about a GitHub project, please include its URL. -->

View File

@@ -0,0 +1,36 @@
---
name: CodeQL False positive
about: Report CodeQL alerts that you think should not have been detected (not applicable, not exploitable, etc.)
title: False positive
labels: false-positive
assignees: ''
---
**Description of the false positive**
<!-- Please explain briefly why you think it shouldn't be included. -->
**Code samples or links to source code**
<!--
For open source code: file links with line numbers on GitHub, for example:
https://github.com/github/codeql/blob/dc440aaee6695deb0d9676b87e06ea984e1b4ae5/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/exec-sh2.js#L10
For closed source code: (redacted) code samples that illustrate the problem, for example:
```
function execSh(command, options) {
return cp.spawn(getShell(), ["-c", command], options) // <- command line injection
};
```
-->
**URL to the alert on GitHub code scanning (optional)**
<!--
1. Open the project on GitHub.com.
2. Switch to the `Security` tab.
3. Browse to the alert that you would like to report.
4. Copy and paste the page URL here.
-->

View File

@@ -56,4 +56,16 @@ jobs:
# do full compile if running on main - this populates the cache
if : ${{ github.event_name != 'pull_request' }}
shell: bash
run: codeql query compile -j0 */ql/src --keep-going --warnings=error
run: |
# Move all the existing cache into another folder, so we only preserve the cache for the current queries.
mkdir -p ${COMBINED_CACHE_DIR}
rm */ql/src/.cache/{lock,size}
# copy the contents of the .cache folders into the combined cache folder.
cp -r */ql/src/.cache/* ${COMBINED_CACHE_DIR}/
# clean up the .cache folders
rm -rf */ql/src/.cache/*
# compile the queries
codeql query compile -j0 */ql/src --keep-going --warnings=error --compilation-cache ${COMBINED_CACHE_DIR}
env:
COMBINED_CACHE_DIR: ${{ github.workspace }}/compilation-dir

View File

@@ -27,7 +27,7 @@ jobs:
with:
filters: |
codegen:
- 'github/workflows/swift.yml'
- '.github/workflows/swift.yml'
- "misc/bazel/**"
- "*.bazel*"
- 'swift/actions/setup-env/**'
@@ -111,7 +111,7 @@ jobs:
- uses: actions/upload-artifact@v3
with:
name: swift-generated-cpp-files
path: swift/generated-cpp-files/**
path: generated-cpp-files/**
database-upgrade-scripts:
runs-on: ubuntu-latest
steps:

View File

@@ -45,4 +45,4 @@ WORKSPACE.bazel @github/codeql-ci-reviewers
/.github/workflows/js-ml-tests.yml @github/codeql-ml-powered-queries-reviewers
/.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers
/.github/workflows/ruby-* @github/codeql-ruby
/.github/workflows/swift-* @github/codeql-c
/.github/workflows/swift.yml @github/codeql-c

View File

@@ -11,11 +11,12 @@
<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.1">
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
</ItemGroup>
<ItemGroup>

View File

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

View File

@@ -1,3 +1,11 @@
## 0.4.5
No user-facing changes.
## 0.4.4
No user-facing changes.
## 0.4.3
### Minor Analysis Improvements

View File

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

View File

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

View File

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

View File

@@ -12,8 +12,8 @@ import IDEContextual
*
* In some cases it is preferable to modify locations (the
* `hasLocationInfo()` predicate) so that they are short, and
* non-overlapping with other locations that might be highlighted in
* the LGTM interface.
* non-overlapping with other locations that might be reported as
* code scanning alerts on GitHub.
*
* We need to give locations that may not be in the database, so
* we use `hasLocationInfo()` rather than `getLocation()`.

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 0.4.4-dev
version: 0.4.5
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -1,3 +1,11 @@
## 0.4.5
No user-facing changes.
## 0.4.4
No user-facing changes.
## 0.4.3
### Minor Analysis Improvements

View File

@@ -12,8 +12,8 @@
*/
/*
* Note: this query is not assigned a precision yet because we don't want it on
* LGTM until its performance is well understood.
* Note: this query is not assigned a precision yet because we don't want it
* to be included in query suites until its performance is well understood.
*/
import cpp

View File

@@ -52,7 +52,7 @@ class Library extends LibraryT {
// The versions reported for C/C++ dependencies are just the versions that
// happen to be installed on the system where the build takes place.
// Reporting those versions is likely to cause misunderstandings, both for
// people reading them and for the vulnerability checker of lgtm.
// people reading them and for vulnerability checkers.
result = "unknown"
}

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 0.4.4-dev
version: 0.4.5
groups:
- cpp
- queries

View File

@@ -6,17 +6,17 @@
<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">
<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.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Autobuild.CSharp\Semmle.Autobuild.CSharp.csproj"/>
<ProjectReference Include="..\Semmle.Autobuild.Shared\Semmle.Autobuild.Shared.csproj"/>
<ProjectReference Include="..\Semmle.Autobuild.CSharp\Semmle.Autobuild.CSharp.csproj" />
<ProjectReference Include="..\Semmle.Autobuild.Shared\Semmle.Autobuild.Shared.csproj" />
</ItemGroup>
</Project>

View File

@@ -11,15 +11,15 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Folder Include="Properties\"/>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="16.11.0"/>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1"/>
<PackageReference Include="Microsoft.Build" Version="17.3.2" />
<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"/>
<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

@@ -8,12 +8,12 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Folder Include="Properties\"/>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="16.11.0"/>
<PackageReference Include="Microsoft.Build" Version="17.3.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\extractor\Semmle.Util\Semmle.Util.csproj"/>
<ProjectReference Include="..\..\extractor\Semmle.Util\Semmle.Util.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
@@ -24,7 +24,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DiaSymReader" Version="1.3.0" />
<PackageReference Include="Microsoft.DiaSymReader" Version="1.4.0" />
<PackageReference Include="Microsoft.DiaSymReader.Native" Version="1.7.0" />
<PackageReference Include="Microsoft.DiaSymReader.PortablePdb" Version="1.6.0"><IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>

View File

@@ -12,17 +12,17 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Extraction.CSharp\Semmle.Extraction.CSharp.csproj"/>
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj"/>
<ProjectReference Include="..\Semmle.Extraction.CSharp\Semmle.Extraction.CSharp.csproj" />
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\"/>
<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"/>
<PackageReference Include="Microsoft.Build" Version="17.3.2" />
<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

@@ -2,6 +2,7 @@ using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace Semmle.Extraction.CSharp.Entities
{
@@ -162,6 +163,13 @@ namespace Semmle.Extraction.CSharp.Entities
operatorName = "false";
break;
default:
var match = Regex.Match(methodName, "^op_Checked(.*)$");
if (match.Success)
{
OperatorSymbol("op_" + match.Groups[1], out var uncheckedName);
operatorName = "checked " + uncheckedName;
break;
}
operatorName = methodName;
success = false;
break;

View File

@@ -10,15 +10,15 @@
<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"/>
<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\"/>
<Folder Include="Properties\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1"/>
<PackageReference Include="Microsoft.Build" Version="16.11.0"/>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.4.0" />
<PackageReference Include="Microsoft.Build" Version="17.3.2" />
</ItemGroup>
</Project>

View File

@@ -6,19 +6,19 @@
<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">
<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.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.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"/>
<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

@@ -12,13 +12,13 @@
<DefineConstants>TRACE;DEBUG;DEBUG_LABELS</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis" Version="4.0.1"/>
<PackageReference Include="Microsoft.CodeAnalysis" Version="4.4.0" />
<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"/>
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj" />
</ItemGroup>
</Project>

View File

@@ -6,14 +6,14 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="xunit" Version="2.4.1"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj"/>
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,3 +1,11 @@
## 1.3.5
No user-facing changes.
## 1.3.4
No user-facing changes.
## 1.3.3
No user-facing changes.

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all
version: 1.3.4-dev
version: 1.3.5
groups:
- csharp
- solorigate

View File

@@ -1,3 +1,11 @@
## 1.3.5
No user-facing changes.
## 1.3.4
No user-facing changes.
## 1.3.3
No user-facing changes.

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries
version: 1.3.4-dev
version: 1.3.5
groups:
- csharp
- solorigate

View File

@@ -1,5 +1,6 @@
import csharp
import semmle.code.csharp.dataflow.internal.SsaImpl::Consistency
import semmle.code.csharp.dataflow.internal.SsaImpl as Impl
import Impl::Consistency
import Ssa
class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition {
@@ -10,6 +11,14 @@ class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition {
}
}
class MyRelevantDefinitionExt extends RelevantDefinitionExt, Impl::DefinitionExt {
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
query predicate localDeclWithSsaDef(LocalVariableDeclExpr d) {
// Local variables in C# must be initialized before every use, so uninitialized
// local variables should not have an SSA definition, as that would imply that

View File

@@ -8,10 +8,10 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
<PackageReference Include="coverlet.collector" Version="3.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.3.0" />
<PackageReference Include="coverlet.collector" Version="3.2.0" />
</ItemGroup>
</Project>

View File

@@ -1,3 +1,13 @@
## 0.4.5
No user-facing changes.
## 0.4.4
### Minor Analysis Improvements
* The `[Summary|Sink|Source]ModelCsv` classes have been deprecated and Models as Data models are defined as data extensions instead.
## 0.4.3
No user-facing changes.

View File

@@ -1,4 +1,5 @@
---
category: minorAnalysis
---
* The `[Summary|Sink|Source]ModelCsv` classes have been deprecated and Models as Data models are defined as data extensions instead.
## 0.4.4
### Minor Analysis Improvements
* The `[Summary|Sink|Source]ModelCsv` classes have been deprecated and Models as Data models are defined as data extensions instead.

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-all
version: 0.4.4-dev
version: 0.4.5
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp

View File

@@ -138,25 +138,6 @@ module Ssa {
}
}
private string getSplitString(Definition def) {
exists(ControlFlow::BasicBlock bb, int i, ControlFlow::Node cfn |
def.definesAt(_, bb, i) and
result = cfn.(ControlFlow::Nodes::ElementNode).getSplitsString()
|
cfn = bb.getNode(i)
or
not exists(bb.getNode(i)) and
cfn = bb.getFirstNode()
)
}
private string getToStringPrefix(Definition def) {
result = "[" + getSplitString(def) + "] "
or
not exists(getSplitString(def)) and
result = ""
}
/**
* A static single assignment (SSA) definition. Either an explicit variable
* definition (`ExplicitDefinition`), an implicit variable definition
@@ -521,8 +502,8 @@ module Ssa {
override string toString() {
if this.getADefinition() instanceof AssignableDefinitions::ImplicitParameterDefinition
then result = getToStringPrefix(this) + "SSA param(" + this.getSourceVariable() + ")"
else result = getToStringPrefix(this) + "SSA def(" + this.getSourceVariable() + ")"
then result = SsaImpl::getToStringPrefix(this) + "SSA param(" + this.getSourceVariable() + ")"
else result = SsaImpl::getToStringPrefix(this) + "SSA def(" + this.getSourceVariable() + ")"
}
override Location getLocation() { result = ad.getLocation() }
@@ -570,8 +551,12 @@ module Ssa {
override string toString() {
if this.getSourceVariable().getAssignable() instanceof LocalScopeVariable
then result = getToStringPrefix(this) + "SSA capture def(" + this.getSourceVariable() + ")"
else result = getToStringPrefix(this) + "SSA entry def(" + this.getSourceVariable() + ")"
then
result =
SsaImpl::getToStringPrefix(this) + "SSA capture def(" + this.getSourceVariable() + ")"
else
result =
SsaImpl::getToStringPrefix(this) + "SSA entry def(" + this.getSourceVariable() + ")"
}
override Location getLocation() { result = this.getCallable().getLocation() }
@@ -612,7 +597,7 @@ module Ssa {
}
override string toString() {
result = getToStringPrefix(this) + "SSA call def(" + this.getSourceVariable() + ")"
result = SsaImpl::getToStringPrefix(this) + "SSA call def(" + this.getSourceVariable() + ")"
}
override Location getLocation() { result = this.getCall().getLocation() }
@@ -640,7 +625,8 @@ module Ssa {
final Definition getQualifierDefinition() { result = q }
override string toString() {
result = getToStringPrefix(this) + "SSA qualifier def(" + this.getSourceVariable() + ")"
result =
SsaImpl::getToStringPrefix(this) + "SSA qualifier def(" + this.getSourceVariable() + ")"
}
override Location getLocation() { result = this.getQualifierDefinition().getLocation() }
@@ -682,7 +668,7 @@ module Ssa {
}
override string toString() {
result = getToStringPrefix(this) + "SSA phi(" + this.getSourceVariable() + ")"
result = SsaImpl::getToStringPrefix(this) + "SSA phi(" + this.getSourceVariable() + ")"
}
/*

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -147,6 +147,12 @@ abstract class Configuration extends string {
*/
FlowFeature getAFeature() { none() }
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
predicate sourceGrouping(Node source, string sourceGroup) { none() }
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
predicate sinkGrouping(Node sink, string sinkGroup) { none() }
/**
* Holds if data may flow from `source` to `sink` for this configuration.
*/
@@ -158,7 +164,7 @@ abstract class Configuration extends string {
* The corresponding paths are generated from the end-points and the graph
* included in the module `PathGraph`.
*/
predicate hasFlowPath(PathNode source, PathNode sink) { flowsTo(source, sink, _, _, this) }
predicate hasFlowPath(PathNode source, PathNode sink) { hasFlowPath(source, sink, this) }
/**
* Holds if data may flow from some source to `sink` for this configuration.
@@ -2712,6 +2718,18 @@ private newtype TPathNode =
state = sink.getState() and
config = sink.getConfiguration()
)
} or
TPathNodeSourceGroup(string sourceGroup, Configuration config) {
exists(PathNodeImpl source |
sourceGroup = source.getSourceGroup() and
config = source.getConfiguration()
)
} or
TPathNodeSinkGroup(string sinkGroup, Configuration config) {
exists(PathNodeSink sink |
sinkGroup = sink.getSinkGroup() and
config = sink.getConfiguration()
)
}
/**
@@ -2920,6 +2938,22 @@ abstract private class PathNodeImpl extends TPathNode {
)
}
string getSourceGroup() {
this.isSource() and
this.getConfiguration().sourceGrouping(this.getNodeEx().asNode(), result)
}
predicate isFlowSource() {
this.isSource() and not exists(this.getSourceGroup())
or
this instanceof PathNodeSourceGroup
}
predicate isFlowSink() {
this = any(PathNodeSink sink | not exists(sink.getSinkGroup())) or
this instanceof PathNodeSinkGroup
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -2959,7 +2993,9 @@ abstract private class PathNodeImpl extends TPathNode {
/** Holds if `n` can reach a sink. */
private predicate directReach(PathNodeImpl n) {
n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor())
n instanceof PathNodeSink or
n instanceof PathNodeSinkGroup or
directReach(n.getANonHiddenSuccessor())
}
/** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */
@@ -3015,6 +3051,12 @@ class PathNode instanceof PathNodeImpl {
/** Holds if this node is a source. */
final predicate isSource() { super.isSource() }
/** Holds if this node is a grouping of source nodes. */
final predicate isSourceGroup(string group) { this = TPathNodeSourceGroup(group, _) }
/** Holds if this node is a grouping of sink nodes. */
final predicate isSinkGroup(string group) { this = TPathNodeSinkGroup(group, _) }
}
/**
@@ -3136,9 +3178,66 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override PathNodeImpl getASuccessorImpl() {
result = TPathNodeSinkGroup(this.getSinkGroup(), config)
}
override predicate isSource() { sourceNode(node, state, config) }
string getSinkGroup() { config.sinkGrouping(node.asNode(), result) }
}
private class PathNodeSourceGroup extends PathNodeImpl, TPathNodeSourceGroup {
string sourceGroup;
Configuration config;
PathNodeSourceGroup() { this = TPathNodeSourceGroup(sourceGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() {
result.getSourceGroup() = sourceGroup and
result.getConfiguration() = config
}
override predicate isSource() { none() }
override string toString() { result = sourceGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private class PathNodeSinkGroup extends PathNodeImpl, TPathNodeSinkGroup {
string sinkGroup;
Configuration config;
PathNodeSinkGroup() { this = TPathNodeSinkGroup(sinkGroup, config) }
override NodeEx getNodeEx() { none() }
override FlowState getState() { none() }
override Configuration getConfiguration() { result = config }
override PathNodeImpl getASuccessorImpl() { none() }
override predicate isSource() { none() }
override string toString() { result = sinkGroup }
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
filepath = "" and startline = 0 and startcolumn = 0 and endline = 0 and endcolumn = 0
}
}
private predicate pathNode(
@@ -3495,6 +3594,15 @@ private module Subpaths {
* Will only have results if `configuration` has non-empty sources and
* sinks.
*/
private predicate hasFlowPath(
PathNodeImpl flowsource, PathNodeImpl flowsink, Configuration configuration
) {
flowsource.isFlowSource() and
flowsource.getConfiguration() = configuration and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
}
private predicate flowsTo(
PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink,
Configuration configuration

View File

@@ -49,7 +49,23 @@ private module SsaInput implements SsaImplCommon::InputSig {
}
}
import SsaImplCommon::Make<SsaInput>
private import SsaImplCommon::Make<SsaInput> as Impl
class Definition = Impl::Definition;
class WriteDefinition = Impl::WriteDefinition;
class UncertainWriteDefinition = Impl::UncertainWriteDefinition;
class PhiNode = Impl::PhiNode;
module Consistency = Impl::Consistency;
module ExposedForTestingOnly {
predicate ssaDefReachesReadExt = Impl::ssaDefReachesReadExt/4;
predicate phiHasInputFromBlockExt = Impl::phiHasInputFromBlockExt/3;
}
/**
* Holds if the `i`th node of basic block `bb` reads source variable `v`.
@@ -1072,7 +1088,7 @@ private predicate adjacentDefRead(
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2,
SsaInput::SourceVariable v
) {
adjacentDefRead(def, bb1, i1, bb2, i2) and
Impl::adjacentDefRead(def, bb1, i1, bb2, i2) and
v = def.getSourceVariable()
}
@@ -1088,7 +1104,7 @@ private predicate adjacentDefReachesRead(
exists(SsaInput::BasicBlock bb3, int i3 |
adjacentDefReachesRead(def, bb1, i1, bb3, i3) and
SsaInput::variableRead(bb3, i3, _, false) and
adjacentDefRead(def, bb3, i3, bb2, i2)
Impl::adjacentDefRead(def, bb3, i3, bb2, i2)
)
}
@@ -1111,11 +1127,11 @@ private predicate adjacentDefReachesUncertainRead(
/** Same as `lastRefRedef`, but skips uncertain reads. */
pragma[nomagic]
private predicate lastRefSkipUncertainReads(Definition def, SsaInput::BasicBlock bb, int i) {
lastRef(def, bb, i) and
Impl::lastRef(def, bb, i) and
not SsaInput::variableRead(bb, i, def.getSourceVariable(), false)
or
exists(SsaInput::BasicBlock bb0, int i0 |
lastRef(def, bb0, i0) and
Impl::lastRef(def, bb0, i0) and
adjacentDefReachesUncertainRead(def, bb, i, bb0, i0)
)
}
@@ -1237,7 +1253,7 @@ private module Cached {
v = def.getSourceVariable() and
capturedReadIn(_, _, v, edef.getSourceVariable(), c, additionalCalls) and
def = def0.getAnUltimateDefinition() and
ssaDefReachesRead(_, def0, bb, i) and
Impl::ssaDefReachesRead(_, def0, bb, i) and
capturedReadIn(bb, i, v, _, _, _) and
c = bb.getNode(i)
)
@@ -1264,18 +1280,18 @@ private module Cached {
cached
predicate isLiveAtEndOfBlock(Definition def, ControlFlow::BasicBlock bb) {
ssaDefReachesEndOfBlock(bb, def, _)
Impl::ssaDefReachesEndOfBlock(bb, def, _)
}
cached
Definition phiHasInputFromBlock(PhiNode phi, ControlFlow::BasicBlock bb) {
phiHasInputFromBlock(phi, result, bb)
Definition phiHasInputFromBlock(Ssa::PhiNode phi, ControlFlow::BasicBlock bb) {
Impl::phiHasInputFromBlock(phi, result, bb)
}
cached
AssignableRead getAReadAtNode(Definition def, ControlFlow::Node cfn) {
exists(Ssa::SourceVariable v, ControlFlow::BasicBlock bb, int i |
ssaDefReachesRead(v, def, bb, i) and
Impl::ssaDefReachesRead(v, def, bb, i) and
variableReadActual(bb, i, v) and
cfn = bb.getNode(i) and
result.getAControlFlowNode() = cfn
@@ -1313,11 +1329,11 @@ private module Cached {
/** Same as `lastRefRedef`, but skips uncertain reads. */
cached
predicate lastRefBeforeRedef(Definition def, ControlFlow::BasicBlock bb, int i, Definition next) {
lastRefRedef(def, bb, i, next) and
Impl::lastRefRedef(def, bb, i, next) and
not SsaInput::variableRead(bb, i, def.getSourceVariable(), false)
or
exists(SsaInput::BasicBlock bb0, int i0 |
lastRefRedef(def, bb0, i0, next) and
Impl::lastRefRedef(def, bb0, i0, next) and
adjacentDefReachesUncertainRead(def, bb, i, bb0, i0)
)
}
@@ -1333,7 +1349,7 @@ private module Cached {
cached
Definition uncertainWriteDefinitionInput(UncertainWriteDefinition def) {
uncertainWriteDefinitionInput(def, result)
Impl::uncertainWriteDefinitionInput(def, result)
}
cached
@@ -1343,10 +1359,57 @@ private module Cached {
v = def.getSourceVariable() and
p = v.getAssignable() and
def = def0.getAnUltimateDefinition() and
ssaDefReachesRead(_, def0, bb, i) and
Impl::ssaDefReachesRead(_, def0, bb, i) and
outRefExitRead(bb, i, v)
)
}
}
import Cached
private string getSplitString(DefinitionExt def) {
exists(ControlFlow::BasicBlock bb, int i, ControlFlow::Node cfn |
def.definesAt(_, bb, i, _) and
result = cfn.(ControlFlow::Nodes::ElementNode).getSplitsString()
|
cfn = bb.getNode(i)
or
not exists(bb.getNode(i)) and
cfn = bb.getFirstNode()
)
}
string getToStringPrefix(DefinitionExt def) {
result = "[" + getSplitString(def) + "] "
or
not exists(getSplitString(def)) and
result = ""
}
/**
* An extended static single assignment (SSA) definition.
*
* This is either a normal SSA definition (`Definition`) or a
* phi-read node (`PhiReadNode`).
*
* Only intended for internal use.
*/
class DefinitionExt extends Impl::DefinitionExt {
override string toString() { result = this.(Ssa::Definition).toString() }
/** Gets the location of this definition. */
Location getLocation() { result = this.(Ssa::Definition).getLocation() }
}
/**
* A phi-read node.
*
* Only intended for internal use.
*/
class PhiReadNode extends DefinitionExt, Impl::PhiReadNode {
override string toString() {
result = getToStringPrefix(this) + "SSA phi read(" + this.getSourceVariable() + ")"
}
override Location getLocation() { result = this.getBasicBlock().getLocation() }
}

View File

@@ -1,3 +1,11 @@
## 0.4.5
No user-facing changes.
## 0.4.4
No user-facing changes.
## 0.4.3
No user-facing changes.

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-queries
version: 0.4.4-dev
version: 0.4.5
groups:
- csharp
- queries

View File

@@ -5,7 +5,8 @@ AnonymousObjectCreation.cs:
# 7| 1: [TypeMention] AnonObj
# 7| 1: [AssignExpr] ... = ...
# 7| 0: [FieldAccess] access to field l
# 7| 1: [ObjectCreation] object creation of type List<AnonObj>
# 7| 1: [CastExpr] (...) ...
# 7| 1: [ObjectCreation] object creation of type List<AnonObj>
# 9| 6: [Property] Prop1
# 9| -1: [TypeMention] int
# 9| 3: [Getter] get_Prop1
@@ -21,13 +22,15 @@ AnonymousObjectCreation.cs:
# 13| 0: [ExprStmt] ...;
# 13| 0: [MethodCall] call to method M1
# 13| -1: [ThisAccess] this access
# 13| 0: [ObjectCreation] object creation of type AnonObj
# 13| -1: [ObjectInitializer] { ..., ... }
# 13| 0: [MemberInitializer] ... = ...
# 13| 0: [PropertyCall] access to property Prop1
# 13| 1: [IntLiteral] 1
# 13| 0: [CastExpr] (...) ...
# 13| 1: [ObjectCreation] object creation of type AnonObj
# 13| -1: [ObjectInitializer] { ..., ... }
# 13| 0: [MemberInitializer] ... = ...
# 13| 0: [PropertyCall] access to property Prop1
# 13| 1: [IntLiteral] 1
# 14| 1: [ReturnStmt] return ...;
# 14| 0: [ObjectCreation] object creation of type AnonObj
# 14| 0: [CastExpr] (...) ...
# 14| 1: [ObjectCreation] object creation of type AnonObj
# 17| 8: [DelegateType] D
#-----| 2: (Parameters)
# 17| 0: [Parameter] x
@@ -42,9 +45,10 @@ AnonymousObjectCreation.cs:
# 21| -1: [TypeMention] D
# 21| 4: [BlockStmt] {...}
# 21| 0: [ReturnStmt] return ...;
# 21| 0: [ExplicitDelegateCreation] delegate creation of type D
# 21| 0: [ImplicitDelegateCreation] delegate creation of type D
# 21| 0: [MethodAccess] access to method M2
# 21| 0: [CastExpr] (...) ...
# 21| 1: [ExplicitDelegateCreation] delegate creation of type D
# 21| 0: [ImplicitDelegateCreation] delegate creation of type D
# 21| 0: [MethodAccess] access to method M2
# 23| 11: [Method] MethodAdd
# 23| -1: [TypeMention] Void
# 24| 4: [BlockStmt] {...}
@@ -53,7 +57,8 @@ AnonymousObjectCreation.cs:
# 25| -1: [TypeMention] List<int>
# 25| 1: [TypeMention] int
# 25| 0: [LocalVariableAccess] access to local variable list
# 25| 1: [ObjectCreation] object creation of type List<Int32>
# 25| 1: [CastExpr] (...) ...
# 25| 1: [ObjectCreation] object creation of type List<Int32>
BinaryPattern.cs:
# 3| [Class] BinaryPattern
# 5| 5: [Property] P1

View File

@@ -1,4 +1,30 @@
| DefUse.cs:63:9:63:14 | this.Field2 | DefUse.cs:80:30:80:31 | access to local variable x1 |
| Fields.cs:65:24:65:32 | this.LoopField | Fields.cs:63:16:63:28 | this access |
| Properties.cs:65:24:65:31 | this.LoopProp | Properties.cs:63:16:63:16 | access to parameter i |
| Test.cs:78:13:78:13 | x | Test.cs:90:9:97:9 | if (...) ... |
phiReadNode
| DefUse.cs:80:30:80:31 | SSA phi read(this.Field2) | DefUse.cs:63:9:63:14 | this.Field2 |
| Fields.cs:63:16:63:28 | SSA phi read(this.LoopField) | Fields.cs:65:24:65:32 | this.LoopField |
| Patterns.cs:20:9:38:9 | SSA phi read(o) | Patterns.cs:7:16:7:16 | o |
| Properties.cs:63:16:63:16 | SSA phi read(this.LoopProp) | Properties.cs:65:24:65:31 | this.LoopProp |
| Test.cs:25:16:25:16 | SSA phi read(x) | Test.cs:8:13:8:13 | x |
| Test.cs:90:9:97:9 | SSA phi read(x) | Test.cs:78:13:78:13 | x |
| Test.cs:99:9:99:15 | SSA phi read(x) | Test.cs:78:13:78:13 | x |
phiReadNodeRead
| DefUse.cs:80:30:80:31 | SSA phi read(this.Field2) | DefUse.cs:63:9:63:14 | this.Field2 | DefUse.cs:80:37:80:42 | access to field Field2 |
| Fields.cs:63:16:63:28 | SSA phi read(this.LoopField) | Fields.cs:65:24:65:32 | this.LoopField | Fields.cs:65:24:65:32 | access to field LoopField |
| Patterns.cs:20:9:38:9 | SSA phi read(o) | Patterns.cs:7:16:7:16 | o | Patterns.cs:20:17:20:17 | access to local variable o |
| Properties.cs:63:16:63:16 | SSA phi read(this.LoopProp) | Properties.cs:65:24:65:31 | this.LoopProp | Properties.cs:65:24:65:31 | access to property LoopProp |
| Test.cs:25:16:25:16 | SSA phi read(x) | Test.cs:8:13:8:13 | x | Test.cs:25:16:25:16 | access to local variable x |
| Test.cs:90:9:97:9 | SSA phi read(x) | Test.cs:78:13:78:13 | x | Test.cs:92:17:92:17 | access to local variable x |
| Test.cs:90:9:97:9 | SSA phi read(x) | Test.cs:78:13:78:13 | x | Test.cs:96:17:96:17 | access to local variable x |
| Test.cs:99:9:99:15 | SSA phi read(x) | Test.cs:78:13:78:13 | x | Test.cs:99:13:99:13 | access to local variable x |
| Test.cs:99:9:99:15 | SSA phi read(x) | Test.cs:78:13:78:13 | x | Test.cs:104:17:104:17 | access to local variable x |
phiReadInput
| DefUse.cs:80:30:80:31 | SSA phi read(this.Field2) | DefUse.cs:63:9:63:18 | SSA def(this.Field2) |
| DefUse.cs:80:30:80:31 | SSA phi read(this.Field2) | DefUse.cs:80:30:80:31 | SSA phi read(this.Field2) |
| Fields.cs:63:16:63:28 | SSA phi read(this.LoopField) | Fields.cs:61:17:61:17 | SSA entry def(this.LoopField) |
| Fields.cs:63:16:63:28 | SSA phi read(this.LoopField) | Fields.cs:63:16:63:28 | SSA phi read(this.LoopField) |
| Patterns.cs:20:9:38:9 | SSA phi read(o) | Patterns.cs:7:16:7:23 | SSA def(o) |
| Properties.cs:63:16:63:16 | SSA phi read(this.LoopProp) | Properties.cs:61:17:61:17 | SSA entry def(this.LoopProp) |
| Properties.cs:63:16:63:16 | SSA phi read(this.LoopProp) | Properties.cs:63:16:63:16 | SSA phi read(this.LoopProp) |
| Test.cs:25:16:25:16 | SSA phi read(x) | Test.cs:24:9:24:15 | SSA phi(x) |
| Test.cs:25:16:25:16 | SSA phi read(x) | Test.cs:25:16:25:16 | SSA phi read(x) |
| Test.cs:90:9:97:9 | SSA phi read(x) | Test.cs:78:13:78:17 | SSA def(x) |
| Test.cs:99:9:99:15 | SSA phi read(x) | Test.cs:90:9:97:9 | SSA phi read(x) |

View File

@@ -1,6 +1,17 @@
import csharp
import semmle.code.csharp.dataflow.internal.SsaImpl
import ExposedForTestingOnly
from Ssa::SourceVariable v, ControlFlow::BasicBlock bb
where phiReadExposedForTesting(bb, v)
select v, bb
query predicate phiReadNode(PhiReadNode phi, Ssa::SourceVariable v) { phi.getSourceVariable() = v }
query predicate phiReadNodeRead(PhiReadNode phi, Ssa::SourceVariable v, ControlFlow::Node read) {
phi.getSourceVariable() = v and
exists(ControlFlow::BasicBlock bb, int i |
ssaDefReachesReadExt(v, phi, bb, i) and
read = bb.getNode(i)
)
}
query predicate phiReadInput(PhiReadNode phi, DefinitionExt inp) {
phiHasInputFromBlockExt(phi, inp, _)
}

View File

@@ -95,7 +95,7 @@ class Test
{
use(x);
}
// no phi_use for `x`, because actual use exists in the block
// phi_use for `x`, even though there is an actual use in the block
use(x);

View File

@@ -168,7 +168,9 @@ generate a database, therefore the build method must be available to the CLI.
Detecting the build system
~~~~~~~~~~~~~~~~~~~~~~~~~~
The CodeQL CLI includes autobuilders for C/C++, C#, Go, and Java code. CodeQL
.. include:: ../reusables/kotlin-beta-note.rst
The CodeQL CLI includes autobuilders for C/C++, C#, Go, Java and Kotlin code. CodeQL
autobuilders allow you to build projects for compiled languages without
specifying any build commands. When an autobuilder is invoked, CodeQL examines
the source for evidence of a build system and attempts to run the optimal set of

View File

@@ -30,7 +30,7 @@ You can then use the CodeQL CLI to publish your pack to share with others. For m
Viewing CodeQL packs and their dependencies in Visual Studio Code
-----------------------------------------------------------------
To download a CodeQL pack that someone else has created, run the **CodeQL: Download Packs** command from the Command Palette.
You can download all the core CodeQL query packs, or enter the full name of a specific pack to download. For example, to download the core queries for analyzing Java, enter ``codeql/java-queries``.
You can download all the core CodeQL query packs, or enter the full name of a specific pack to download. For example, to download the core queries for analyzing Java or Kotlin, enter ``codeql/java-queries``.
Whether you have downloaded a CodeQL pack or created your own, you can open the ``qlpack.yml`` file in the root of a CodeQL pack directory in Visual Studio Code and view the dependencies section to see what libraries the pack depends on.

View File

@@ -7,6 +7,10 @@ CodeQL has a large selection of classes for representing the abstract syntax tre
.. include:: ../reusables/abstract-syntax-tree.rst
.. include:: ../reusables/kotlin-beta-note.rst
.. include:: ../reusables/kotlin-java-differences.rst
Statement classes
-----------------

View File

@@ -47,7 +47,7 @@ Example finding unreachable AST nodes
where not exists(node.getAFlowNode())
select node
`See this in the query console on LGTM.com <https://lgtm.com/query/669220024/>`__. The demo projects on LGTM.com all have some code that has no control flow node, and is therefore unreachable. However, since the ``Module`` class is also a subclass of the ``AstNode`` class, the query also finds any modules implemented in C or with no source code. Therefore, it is better to find all unreachable statements.
Many codebases have some code that has no control flow node, and is therefore unreachable. However, since the ``Module`` class is also a subclass of the ``AstNode`` class, the query also finds any modules implemented in C or with no source code. Therefore, it is better to find all unreachable statements.
Example finding unreachable statements
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -60,7 +60,7 @@ Example finding unreachable statements
where not exists(s.getAFlowNode())
select s
`See this in the query console on LGTM.com <https://lgtm.com/query/670720181/>`__. This query gives fewer results, but most of the projects have some unreachable nodes. These are also highlighted by the standard "Unreachable code" query. For more information, see `Unreachable code <https://lgtm.com/rules/3980095>`__ on LGTM.com.
This query should give fewer results. You can also find unreachable code using the standard "Unreachable code" query. For more information, see `Unreachable code <https://codeql.github.com/codeql-query-help/python/py-unreachable-statement/>`__.
The ``BasicBlock`` class
------------------------
@@ -114,7 +114,7 @@ Example finding mutually exclusive blocks within the same function
)
select b1, b2
`See this in the query console on LGTM.com <https://lgtm.com/query/671000028/>`__. This typically gives a very large number of results, because it is a common occurrence in normal control flow. It is, however, an example of the sort of control-flow analysis that is possible. Control-flow analyses such as this are an important aid to data flow analysis. For more information, see ":doc:`Analyzing data flow in Python <analyzing-data-flow-in-python>`."
This typically gives a very large number of results, because it is a common occurrence in normal control flow. It is, however, an example of the sort of control-flow analysis that is possible. Control-flow analyses such as this are an important aid to data flow analysis. For more information, see ":doc:`Analyzing data flow in Python <analyzing-data-flow-in-python>`."
Further reading
---------------

View File

@@ -5,6 +5,10 @@ Analyzing data flow in Java
You can use CodeQL to track the flow of data through a Java program to its use.
.. include:: ../reusables/kotlin-beta-note.rst
.. include:: ../reusables/kotlin-java-differences.rst
About this article
------------------

View File

@@ -97,11 +97,9 @@ Python has builtin functionality for reading and writing files, such as the func
call = API::moduleImport("os").getMember("open").getACall()
select call.getArg(0)
`See this in the query console on LGTM.com <https://lgtm.com/query/8635258505893505141/>`__. Two of the demo projects make use of this low-level API.
Notice the use of the ``API`` module for referring to library functions. For more information, see ":doc:`Using API graphs in Python <using-api-graphs-in-python>`."
Unfortunately this will only give the expression in the argument, not the values which could be passed to it. So we use local data flow to find all expressions that flow into the argument:
Unfortunately this query will only give the expression in the argument, not the values which could be passed to it. So we use local data flow to find all expressions that flow into the argument:
.. code-block:: ql
@@ -115,9 +113,7 @@ Unfortunately this will only give the expression in the argument, not the values
DataFlow::localFlow(expr, call.getArg(0))
select call, expr
`See this in the query console on LGTM.com <https://lgtm.com/query/8213643003890447109/>`__. Many expressions flow to the same call.
We see that we get several data-flow nodes for an expression as it flows towards a call (notice repeated locations in the ``call`` column). We are mostly interested in the "first" of these, what might be called the local source for the file name. To restrict attention to such local sources, and to simultaneously make the analysis more performant, we have the QL class ``LocalSourceNode``. We could demand that ``expr`` is such a node:
Typically, you will see several data-flow nodes for an expression as it flows towards a call (notice repeated locations in the ``call`` column). We are mostly interested in the "first" of these, what might be called the local source for the file name. To restrict attention to such local sources, and to simultaneously make the analysis more performant, we have the QL class ``LocalSourceNode``. We could demand that ``expr`` is such a node:
.. code-block:: ql
@@ -160,9 +156,9 @@ As an alternative, we can ask more directly that ``expr`` is a local source of t
expr = call.getArg(0).getALocalSource()
select call, expr
`See this in the query console on LGTM.com <https://lgtm.com/query/6602079735954016687/>`__. All these three queries give identical results. We now mostly have one expression per call.
These three queries all give identical results. We now mostly have one expression per call.
We still have some cases of more than one expression flowing to a call, but then they flow through different code paths (possibly due to control-flow splitting, as in the second case).
We still have some cases of more than one expression flowing to a call, but then they flow through different code paths (possibly due to control-flow splitting).
We might want to make the source more specific, for example a parameter to a function or method. This query finds instances where a parameter is used as the name when opening a file:
@@ -178,7 +174,7 @@ We might want to make the source more specific, for example a parameter to a fun
DataFlow::localFlow(p, call.getArg(0))
select call, p
`See this in the query console on LGTM.com <https://lgtm.com/query/3998032643497238063/>`__. Very few results now; these could feasibly be inspected manually.
For most codebases, this will return only a few results and these could be inspected manually.
Using the exact name supplied via the parameter may be too strict. If we want to know if the parameter influences the file name, we can use taint tracking instead of data flow. This query finds calls to ``os.open`` where the filename is derived from a parameter:
@@ -194,7 +190,7 @@ Using the exact name supplied via the parameter may be too strict. If we want to
TaintTracking::localTaint(p, call.getArg(0))
select call, p
`See this in the query console on LGTM.com <https://lgtm.com/query/2129957933670836953/>`__. Now we get more results and in more projects.
Typically, this finds more results.
Global data flow
----------------
@@ -369,8 +365,6 @@ This data flow configuration tracks data flow from environment variables to open
select fileOpen, "This call to 'os.open' uses data from $@.",
environment, "call to 'os.getenv'"
`Running this in the query console on LGTM.com <https://lgtm.com/query/6582374907796191895/>`__ unsurprisingly yields no results in the demo projects.
Further reading
---------------

View File

@@ -51,7 +51,7 @@ We could then write this query to find all ``@SuppressWarnings`` annotations att
anntp.hasQualifiedName("java.lang", "SuppressWarnings")
select ann, ann.getValue("value")
`See the full query in the query console on LGTM.com <https://lgtm.com/query/1775658606775222283/>`__. Several of the LGTM.com demo projects use the ``@SuppressWarnings`` annotation. Looking at the ``value``\ s of the annotation element returned by the query, we can see that the *apache/activemq* project uses the ``"rawtypes"`` value described above.
If the codebase you are analyzing uses the ``@SuppressWarnings`` annotation, you can check the ``value``\ s of the annotation element returned by the query. They should use the ``"rawtypes"`` value described above.
As another example, this query finds all annotation types that only have a single annotation element, which has name ``value``:
@@ -66,8 +66,6 @@ As another example, this query finds all annotation types that only have a singl
)
select anntp
`See the full query in the query console on LGTM.com <https://lgtm.com/query/2145264152490258283/>`__.
Example: Finding missing ``@Override`` annotations
--------------------------------------------------
@@ -124,7 +122,7 @@ This makes it very easy to write our query for finding methods that override ano
not overriding.getAnAnnotation() instanceof OverrideAnnotation
select overriding, "Method overrides another method, but does not have an @Override annotation."
`See this in the query console on LGTM.com <https://lgtm.com/query/7419756266089837339/>`__. In practice, this query may yield many results from compiled library code, which aren't very interesting. It's therefore a good idea to add another conjunct ``overriding.fromSource()`` to restrict the result to only report methods for which source code is available.
In practice, this query may yield many results from compiled library code, which aren't very interesting. It's therefore a good idea to add another conjunct ``overriding.fromSource()`` to restrict the result to only report methods for which source code is available.
Example: Finding calls to deprecated methods
--------------------------------------------
@@ -237,7 +235,7 @@ Now we can extend our query to filter out calls in methods carrying a ``Suppress
and not call.getCaller().getAnAnnotation() instanceof SuppressDeprecationWarningAnnotation
select call, "This call invokes a deprecated method."
`See this in the query console on LGTM.com <https://lgtm.com/query/8706367340403790260/>`__. It's fairly common for projects to contain calls to methods that appear to be deprecated.
It's fairly common for projects to contain calls to methods that appear to be deprecated.
Further reading
---------------

View File

@@ -3,7 +3,9 @@
Basic query for C and C++ code
==============================
Learn to write and run a simple CodeQL query using LGTM.
Learn to write and run a simple CodeQL query using Visual Studio Code with the CodeQL extension.
.. include:: ../reusables/vs-code-basic-instructions/setup-to-run-queries.rst
About the query
---------------
@@ -14,62 +16,33 @@ The query we're going to run performs a basic search of the code for ``if`` stat
if (error) { }
Running the query
-----------------
.. include:: ../reusables/vs-code-basic-instructions/find-database.rst
#. In the main search box on LGTM.com, search for the project you want to query. For tips, see `Searching <https://lgtm.com/help/lgtm/searching>`__.
Running a quick query
---------------------
#. Click the project in the search results.
.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-1.rst
#. Click **Query this project**.
This opens the query console. (For information about using this, see `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.)
.. pull-quote::
Note
Alternatively, you can go straight to the query console by clicking **Query console** (at the top of any page), selecting **C/C++** from the **Language** drop-down list, then choosing one or more projects to query from those displayed in the **Project** drop-down list.
#. Copy the following query into the text box in the query console:
#. In the quick query tab, delete ``select ""`` and paste the following query beneath the import statement ``import cpp``.
.. code-block:: ql
import cpp
from IfStmt ifstmt, BlockStmt block
where ifstmt.getThen() = block and
block.getNumStmt() = 0
select ifstmt, "This 'if' statement is redundant."
LGTM checks whether your query compiles and, if all is well, the **Run** button changes to green to indicate that you can go ahead and run the query.
.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-2.rst
#. Click **Run**.
.. image:: ../images/codeql-for-visual-studio-code/basic-cpp-query-results-1.png
:align: center
The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation:
If any matching code is found, click a link in the ``ifstmt`` column to open the file and highlight the matching ``if`` statement.
.. image:: ../images/query-progress.png
:align: center
.. image:: ../images/codeql-for-visual-studio-code/basic-cpp-query-results-2.png
:align: center
.. pull-quote::
Note
Your query is always run against the most recently analyzed commit to the selected project.
The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs. The second column is the alert message.
`Example query results <https://lgtm.com/query/4242591143131494898/>`__
.. pull-quote::
Note
An ellipsis (…) at the bottom of the table indicates that the entire list is not displayed—click it to show more results.
#. If any matching code is found, click a link in the ``ifstmt`` column to view the ``if`` statement in the code viewer.
The matching ``if`` statement is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code.
.. include:: ../reusables/vs-code-basic-instructions/note-store-quick-query.rst
About the query structure
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -120,7 +93,7 @@ In this case, identifying the ``if`` statement with the empty ``then`` branch as
To exclude ``if`` statements that have an ``else`` branch:
#. Extend the ``where`` clause to include the following extra condition:
#. Edit your query and extend the ``where`` clause to include the following extra condition:
.. code-block:: ql
@@ -134,14 +107,24 @@ To exclude ``if`` statements that have an ``else`` branch:
block.getNumStmt() = 0 and
not ifstmt.hasElse()
#. Click **Run**.
#. Re-run the query.
There are now fewer results because ``if`` statements with an ``else`` branch are no longer reported.
`See this in the query console <https://lgtm.com/query/1899933116489579248/>`__
Further reading
---------------
.. include:: ../reusables/cpp-further-reading.rst
.. include:: ../reusables/codeql-ref-tools-further-reading.rst
.. Article-specific substitutions for the reusables used in docs/codeql/reusables/vs-code-basic-instructions
.. |language-text| replace:: C/C++
.. |language-code| replace:: ``cpp``
.. |example-url| replace:: https://github.com/protocolbuffers/protobuf
.. |image-quick-query| image:: ../images/codeql-for-visual-studio-code/quick-query-tab-cpp.png
.. |result-col-1| replace:: The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs.

View File

@@ -3,7 +3,9 @@
Basic query for C# code
=======================
Learn to write and run a simple CodeQL query using LGTM.
Learn to write and run a simple CodeQL query using Visual Studio Code with the CodeQL extension.
.. include:: ../reusables/vs-code-basic-instructions/setup-to-run-queries.rst
About the query
---------------
@@ -14,62 +16,33 @@ The query we're going to run performs a basic search of the code for ``if`` stat
if (error) { }
Running the query
-----------------
.. include:: ../reusables/vs-code-basic-instructions/find-database.rst
#. In the main search box on LGTM.com, search for the project you want to query. For tips, see `Searching <https://lgtm.com/help/lgtm/searching>`__.
Running a quick query
---------------------
#. Click the project in the search results.
.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-1.rst
#. Click **Query this project**.
This opens the query console. (For information about using this, see `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.)
.. pull-quote::
Note
Alternatively, you can go straight to the query console by clicking **Query console** (at the top of any page), selecting **C#** from the **Language** drop-down list, then choosing one or more projects to query from those displayed in the **Project** drop-down list.
#. Copy the following query into the text box in the query console:
#. In the quick query tab, delete ``select ""`` and paste the following query beneath the import statement ``import csharp``.
.. code-block:: ql
import csharp
from IfStmt ifstmt, BlockStmt block
where ifstmt.getThen() = block and
block.isEmpty()
select ifstmt, "This 'if' statement is redundant."
LGTM checks whether your query compiles and, if all is well, the **Run** button changes to green to indicate that you can go ahead and run the query.
.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-2.rst
#. Click **Run**.
.. image:: ../images/codeql-for-visual-studio-code/basic-csharp-query-results-1.png
:align: center
The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation:
If any matching code is found, click a link in the ``ifstmt`` column to open the file and highlight the matching ``if`` statement.
.. image:: ../images/query-progress.png
:align: center
.. image:: ../images/codeql-for-visual-studio-code/basic-csharp-query-results-2.png
:align: center
.. pull-quote::
Note
Your query is always run against the most recently analyzed commit to the selected project.
The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs. The second column is the alert message.
`Example query results <https://lgtm.com/query/1214010107827821393/>`__
.. pull-quote::
Note
An ellipsis (…) at the bottom of the table indicates that the entire list is not displayed—click it to show more results.
#. If any matching code is found, click a link in the ``ifstmt`` column to view the ``if`` statement in the code viewer.
The matching ``if`` statement is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code.
.. include:: ../reusables/vs-code-basic-instructions/note-store-quick-query.rst
About the query structure
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -139,14 +112,23 @@ To exclude ``if`` statements that have an ``else`` branch:
block.isEmpty() and
not exists(ifstmt.getElse())
#. Click **Run**.
#. Re-run the query.
There are now fewer results because ``if`` statements with an ``else`` branch are no longer included.
`See this in the query console <https://lgtm.com/query/6233102733683510530/>`__
Further reading
---------------
.. include:: ../reusables/csharp-further-reading.rst
.. include:: ../reusables/codeql-ref-tools-further-reading.rst
.. Article-specific substitutions for the reusables used in docs/codeql/reusables/vs-code-basic-instructions
.. |language-text| replace:: C#
.. |language-code| replace:: ``csharp``
.. |example-url| replace:: https://github.com/PowerShell/PowerShell
.. |image-quick-query| image:: ../images/codeql-for-visual-studio-code/quick-query-tab-csharp.png
.. |result-col-1| replace:: The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs.

View File

@@ -3,7 +3,9 @@
Basic query for Go code
=======================
Learn to write and run a simple CodeQL query using LGTM.
Learn to write and run a simple CodeQL query using Visual Studio Code with the CodeQL extension.
.. include:: ../reusables/vs-code-basic-instructions/setup-to-run-queries.rst
About the query
---------------
@@ -22,29 +24,17 @@ This is problematic because the receiver argument is passed by value, not by ref
For further information on using methods on values or pointers in Go, see the `Go FAQ <https://golang.org/doc/faq#methods_on_values_or_pointers>`__.
Running the query
-----------------
.. include:: ../reusables/vs-code-basic-instructions/find-database.rst
#. In the main search box on LGTM.com, search for the project you want to query. For tips, see `Searching <https://lgtm.com/help/lgtm/searching>`__.
Running a quick query
---------------------
#. Click the project in the search results.
.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-1.rst
#. Click **Query this project**.
This opens the query console. (For information about using this, see `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.)
.. pull-quote::
Note
Alternatively, you can go straight to the query console by clicking **Query console** (at the top of any page), selecting **Go** from the **Language** drop-down list, then choosing one or more projects to query from those displayed in the **Project** drop-down list.
#. Copy the following query into the text box in the query console:
#. In the quick query tab, delete ``select ""`` and paste the following query beneath the import statement ``import go``.
.. code-block:: ql
import go
from Method m, Variable recv, Write w, Field f
where
recv = m.getReceiver() and
@@ -52,34 +42,17 @@ Running the query
not recv.getType() instanceof PointerType
select w, "This update to " + f + " has no effect, because " + recv + " is not a pointer."
LGTM checks whether your query compiles and, if all is well, the **Run** button changes to green to indicate that you can go ahead and run the query.
.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-2.rst
#. Click **Run**.
.. image:: ../images/codeql-for-visual-studio-code/basic-go-query-results-1.png
:align: center
The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation:
If any matching code is found, click a link in the ``w`` column to open the file and highlight the matching location.
.. image:: ../images/query-progress.png
:align: center
.. image:: ../images/codeql-for-visual-studio-code/basic-go-query-results-2.png
:align: center
.. pull-quote::
Note
Your query is always run against the most recently analyzed commit to the selected project.
The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to ``w``, which is the location in the source code where the receiver ``recv`` is modified. The second column is the alert message.
`Example query results <https://lgtm.com/query/6221190009056970603/>`__
.. pull-quote::
Note
An ellipsis (…) at the bottom of the table indicates that the entire list is not displayed—click it to show more results.
#. If any matching code is found, click a link in the ``w`` column to view it in the code viewer.
The matching ``w`` is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code.
.. include:: ../reusables/vs-code-basic-instructions/note-store-quick-query.rst
About the query structure
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -140,14 +113,24 @@ To exclude these values:
not recv.getType() instanceof PointerType and
not exists(ReturnStmt ret | ret.getExpr() = recv.getARead().asExpr())
#. Click **Run**.
#. Re-run the query.
There are now fewer results because value methods that return their receiver variable are no longer reported.
`See this in the query console <https://lgtm.com/query/9110448975027954322/>`__
Further reading
---------------
.. include:: ../reusables/go-further-reading.rst
.. include:: ../reusables/codeql-ref-tools-further-reading.rst
.. Article-specific substitutions for the reusables used in docs/codeql/reusables/vs-code-basic-instructions
.. |language-text| replace:: Go
.. |language-code| replace:: ``go``
.. |example-url| replace:: https://github.com/go-gorm/gorm
.. |image-quick-query| image:: ../images/codeql-for-visual-studio-code/quick-query-tab-go.png
.. |result-col-1| replace:: The first column corresponds to ``w``, which is the location in the source code where the receiver ``recv`` is modified.

View File

@@ -1,100 +1,90 @@
.. _basic-query-for-java-code:
Basic query for Java code
=========================
Basic query for Java and Kotlin code
====================================
Learn to write and run a simple CodeQL query using LGTM.
Learn to write and run a simple CodeQL query using Visual Studio Code with the CodeQL extension.
.. include:: ../reusables/vs-code-basic-instructions/setup-to-run-queries.rst
About the query
---------------
The query we're going to run performs a basic search of the code for ``if`` statements that are redundant, in the sense that they have an empty then branch. For example, code such as:
The query we're going to run searches for inefficient tests for empty strings. For example, Java code such as:
.. code-block:: java
if (error) { }
public class TestJava {
void myJavaFun(String s) {
boolean b = s.equals("");
}
}
Running the query
-----------------
or Kotlin code such as:
#. In the main search box on LGTM.com, search for the project you want to query. For tips, see `Searching <https://lgtm.com/help/lgtm/searching>`__.
.. code-block:: kotlin
#. Click the project in the search results.
void myKotlinFun(s: String) {
var b = s.equals("")
}
#. Click **Query this project**.
In either case, replacing ``s.equals("")`` with ``s.isEmpty()``
would be more efficient.
This opens the query console. (For information about using this, see `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.)
.. include:: ../reusables/vs-code-basic-instructions/find-database.rst
.. pull-quote::
Running a quick query
---------------------
Note
.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-1.rst
Alternatively, you can go straight to the query console by clicking **Query console** (at the top of any page), selecting **Java** from the **Language** drop-down list, then choosing one or more projects to query from those displayed in the **Project** drop-down list.
#. Copy the following query into the text box in the query console:
#. In the quick query tab, delete ``select ""`` and paste the following query beneath the import statement ``import java``.
.. code-block:: ql
import java
from MethodAccess ma
where
ma.getMethod().hasName("equals") and
ma.getArgument(0).(StringLiteral).getValue() = ""
select ma, "This comparison to empty string is inefficient, use isEmpty() instead."
from IfStmt ifstmt, Block block
where ifstmt.getThen() = block and
block.getNumStmt() = 0
select ifstmt, "This 'if' statement is redundant."
Note that CodeQL treats Java and Kotlin as part of the same language, so even though this query starts with ``import java``, it will work for both Java and Kotlin code.
LGTM checks whether your query compiles and, if all is well, the **Run** button changes to green to indicate that you can go ahead and run the query.
.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-2.rst
#. Click **Run**.
.. image:: ../images/codeql-for-visual-studio-code/basic-java-query-results-1.png
:align: center
The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation:
If any matching code is found, click a link in the ``ma`` column to view the ``.equals`` expression in the code viewer.
.. image:: ../images/query-progress.png
:align: center
.. image:: ../images/codeql-for-visual-studio-code/basic-java-query-results-2.png
:align: center
.. pull-quote::
Note
Your query is always run against the most recently analyzed commit to the selected project.
The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs. The second column is the alert message.
`Example query results <https://lgtm.com/query/3235645104630320782/>`__
.. pull-quote::
Note
An ellipsis (…) at the bottom of the table indicates that the entire list is not displayed—click it to show more results.
#. If any matching code is found, click a link in the ``ifstmt`` column to view the ``if`` statement in the code viewer.
The matching ``if`` statement is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code.
.. include:: ../reusables/vs-code-basic-instructions/note-store-quick-query.rst
About the query structure
~~~~~~~~~~~~~~~~~~~~~~~~~
After the initial ``import`` statement, this simple query comprises three parts that serve similar purposes to the FROM, WHERE, and SELECT parts of an SQL query.
+---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+
| Query part | Purpose | Details |
+===============================================================+===================================================================================================================+========================================================================================================================+
| ``import java`` | Imports the standard CodeQL libraries for Java. | Every query begins with one or more ``import`` statements. |
+---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+
| ``from IfStmt ifstmt, Block block`` | Defines the variables for the query. | We use: |
| | Declarations are of the form: | |
| | ``<type> <variable name>`` | - an ``IfStmt`` variable for ``if`` statements |
| | | - a ``Block`` variable for the then block |
+---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+
| ``where ifstmt.getThen() = block and block.getNumStmt() = 0`` | Defines a condition on the variables. | ``ifstmt.getThen() = block`` relates the two variables. The block must be the ``then`` branch of the ``if`` statement. |
| | | |
| | | ``block.getNumStmt() = 0`` states that the block must be empty (that is, it contains no statements). |
+---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+
| ``select ifstmt, "This 'if' statement is redundant."`` | Defines what to report for each match. | Reports the resulting ``if`` statement with a string that explains the problem. |
| | | |
| | ``select`` statements for queries that are used to find instances of poor coding practice are always in the form: | |
| | ``select <program element>, "<alert message>"`` | |
+---------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------+
+--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+
| Query part | Purpose | Details |
+==================================================================================================+===================================================================================================================+===================================================================================================+
| ``import java`` | Imports the standard CodeQL libraries for Java and Kotlin. | Every query begins with one or more ``import`` statements. |
+--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+
| ``from MethodAccess ma`` | Defines the variables for the query. | We use: |
| | Declarations are of the form: | |
| | ``<type> <variable name>`` | - a ``MethodAccess`` variable for call expressions |
+--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+
| ``where ma.getMethod().hasName("equals") and ma.getArgument(0).(StringLiteral).getValue() = ""`` | Defines a condition on the variables. | ``ma.getMethod().hasName("equals")`` restricts ``ma`` to only calls to methods call ``equals``. |
| | | |
| | | ``ma.getArgument(0).(StringLiteral).getValue() = ""`` says the argument must be literal ``""``. |
+--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+
| ``select ma, "This comparison to empty string is inefficient, use isEmpty() instead."`` | Defines what to report for each match. | Reports the resulting ``.equals`` expression with a string that explains the problem. |
| | | |
| | ``select`` statements for queries that are used to find instances of poor coding practice are always in the form: | |
| | ``select <program element>, "<alert message>"`` | |
+--------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+
Extend the query
----------------
@@ -104,44 +94,51 @@ Query writing is an inherently iterative process. You write a simple query and t
Remove false positive results
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Browsing the results of our basic query shows that it could be improved. Among the results you are likely to find examples of ``if`` statements with an ``else`` branch, where an empty ``then`` branch does serve a purpose. For example:
Browsing the results of our basic query shows that it could be improved. For example, you may find results for code like:
.. code-block:: java
if (...) {
...
} else if ("-verbose".equals(option)) {
// nothing to do - handled earlier
} else {
error("unrecognized option");
}
public class TestJava {
void myJavaFun(Object o) {
boolean b = o.equals("");
}
}
In this case, identifying the ``if`` statement with the empty ``then`` branch as redundant is a false positive. One solution to this is to modify the query to ignore empty ``then`` branches if the ``if`` statement has an ``else`` branch.
To exclude ``if`` statements that have an ``else`` branch:
In this case, it is not possible to simply use ``o.isEmpty()`` instead, as ``o`` has type ``Object`` rather than ``String``. One solution to this is to modify the query to only return results where the expression being tested has type ``String``:
#. Extend the where clause to include the following extra condition:
.. code-block:: ql
and not exists(ifstmt.getElse())
ma.getQualifier().getType() instanceof TypeString
The ``where`` clause is now:
.. code-block:: ql
where ifstmt.getThen() = block and
block.getNumStmt() = 0 and
not exists(ifstmt.getElse())
where
ma.getQualifier().getType() instanceof TypeString and
ma.getMethod().hasName("equals") and
ma.getArgument(0).(StringLiteral).getValue() = ""
#. Click **Run**.
#. Re-run the query.
There are now fewer results because ``if`` statements with an ``else`` branch are no longer included.
`See this in the query console <https://lgtm.com/query/6382189874776576029/>`__
There are now fewer results because ``.equals`` expressions with different types are no longer included.
Further reading
---------------
.. include:: ../reusables/java-further-reading.rst
.. include:: ../reusables/codeql-ref-tools-further-reading.rst
.. Article-specific substitutions for the reusables used in docs/codeql/reusables/vs-code-basic-instructions
.. |language-text| replace:: Java
.. |language-code| replace:: ``java``
.. |example-url| replace:: https://github.com/apache/activemq
.. |image-quick-query| image:: ../images/codeql-for-visual-studio-code/quick-query-tab-java.png
.. |result-col-1| replace:: The first column corresponds to the expression ``ma`` and is linked to the location in the source code of the project where ``ma`` occurs.

View File

@@ -3,7 +3,9 @@
Basic query for JavaScript code
===============================
Learn to write and run a simple CodeQL query using LGTM.
Learn to write and run a simple CodeQL query using Visual Studio Code with the CodeQL extension.
.. include:: ../reusables/vs-code-basic-instructions/setup-to-run-queries.rst
About the query
---------------
@@ -12,62 +14,33 @@ In JavaScript, any expression can be turned into an expression statement. While
The query you will run finds instances of this problem. The query searches for expressions ``e`` that are pure—that is, their evaluation does not lead to any side effects—but appear as an expression statement.
Running the query
-----------------
.. include:: ../reusables/vs-code-basic-instructions/find-database.rst
#. In the main search box on LGTM.com, search for the project you want to query. For tips, see `Searching <https://lgtm.com/help/lgtm/searching>`__.
Running a quick query
---------------------
#. Click the project in the search results.
.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-1.rst
#. Click **Query this project**.
This opens the query console. (For information about using this, see `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.)
.. pull-quote::
Note
Alternatively, you can go straight to the query console by clicking **Query console** (at the top of any page), selecting **JavaScript** from the **Language** drop-down list, then choosing one or more projects to query from those displayed in the **Project** drop-down list.
#. Copy the following query into the text box in the query console:
#. In the quick query tab, delete ``select ""`` and paste the following query beneath the import statement ``import javascript``.
.. code-block:: ql
import javascript
from Expr e
where e.isPure() and
e.getParent() instanceof ExprStmt
select e, "This expression has no effect."
LGTM checks whether your query compiles and, if all is well, the **Run** button changes to green to indicate that you can go ahead and run the query.
.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-2.rst
#. Click **Run**.
.. image:: ../images/codeql-for-visual-studio-code/basic-js-query-results-1.png
:align: center
The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation:
If any matching code is found, click one of the links in the ``e`` column to open the file and highlight the matching expression.
.. image:: ../images/query-progress.png
:align: center
.. image:: ../images/codeql-for-visual-studio-code/basic-js-query-results-2.png
:align: center
.. pull-quote::
Note
Your query is always run against the most recently analyzed commit to the selected project.
The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to the expression ``e`` and is linked to the location in the source code of the project where ``e`` occurs. The second column is the alert message.
`Example query results <https://lgtm.com/query/5137013631828816943/>`__
.. pull-quote::
Note
An ellipsis (…) at the bottom of the table indicates that the entire list is not displayed—click it to show more results.
#. If any matching code is found, click one of the links in the ``e`` column to view the expression in the code viewer.
The matching statement is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code.
.. include:: ../reusables/vs-code-basic-instructions/note-store-quick-query.rst
About the query structure
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -119,11 +92,14 @@ To remove directives from the results:
e.getParent() instanceof ExprStmt and
not e.getParent() instanceof Directive
#. Click **Run**.
#. Re-run the query.
There are now fewer results as ``use strict`` directives are no longer reported.
The improved query finds several results on the example project including `this result <https://lgtm.com/projects/g/ajaxorg/ace/rev/ad50673d7137c09d1a5a6f0ef83633a149f9e3d1/files/lib/ace/keyboard/vim.js#L320>`__:
The improved query finds several results on the example project including the result below:
.. image:: ../images/codeql-for-visual-studio-code/basic-js-query-results-1.png
:align: center
.. code-block:: javascript
@@ -136,3 +112,15 @@ Further reading
.. include:: ../reusables/javascript-further-reading.rst
.. include:: ../reusables/codeql-ref-tools-further-reading.rst
.. Article-specific substitutions for the reusables used in docs/codeql/reusables/vs-code-basic-instructions
.. |language-text| replace:: JavaScript/TypeScript
.. |language-code| replace:: ``javascript``
.. |example-url| replace:: https://github.com/ajaxorg/ace
.. |image-quick-query| image:: ../images/codeql-for-visual-studio-code/quick-query-tab-js.png
.. |result-col-1| replace:: The first column corresponds to the expression ``e`` and is linked to the location in the source code of the project where ``e`` occurs.

View File

@@ -3,7 +3,9 @@
Basic query for Python code
===========================
Learn to write and run a simple CodeQL query using LGTM.
Learn to write and run a simple CodeQL query using Visual Studio Code with the CodeQL extension.
.. include:: ../reusables/vs-code-basic-instructions/setup-to-run-queries.rst
About the query
---------------
@@ -14,62 +16,33 @@ The query we're going to run performs a basic search of the code for ``if`` stat
if error: pass
Running the query
-----------------
.. include:: ../reusables/vs-code-basic-instructions/find-database.rst
#. In the main search box on LGTM.com, search for the project you want to query. For tips, see `Searching <https://lgtm.com/help/lgtm/searching>`__.
Running a quick query
---------------------
#. Click the project in the search results.
.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-1.rst
#. Click **Query this project**.
This opens the query console. (For information about using this, see `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.)
.. pull-quote::
Note
Alternatively, you can go straight to the query console by clicking **Query console** (at the top of any page), selecting **Python** from the **Language** drop-down list, then choosing one or more projects to query from those displayed in the **Project** drop-down list.
#. Copy the following query into the text box in the query console:
#. In the quick query tab, delete ``select ""`` and paste the following query beneath the import statement ``import python``.
.. code-block:: ql
import python
from If ifstmt, Stmt pass
where pass = ifstmt.getStmt(0) and
pass instanceof Pass
select ifstmt, "This 'if' statement is redundant."
LGTM checks whether your query compiles and, if all is well, the **Run** button changes to green to indicate that you can go ahead and run the query.
.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-2.rst
#. Click **Run**.
.. image:: ../images/codeql-for-visual-studio-code/basic-python-query-results-1.png
:align: center
The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation:
If any matching code is found, click a link in the ``ifstmt`` column to open the file and highlight the matching ``if`` statement.
.. image:: ../images/query-progress.png
:align: center
.. image:: ../images/codeql-for-visual-studio-code/basic-python-query-results-2.png
:align: center
.. pull-quote::
Note
Your query is always run against the most recently analyzed commit to the selected project.
The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs. The second column is the alert message.
`Example query results <https://lgtm.com/query/3592297537117272922/>`__
.. pull-quote::
Note
An ellipsis (…) at the bottom of the table indicates that the entire list is not displayed—click it to show more results.
#. If any matching code is found, click a link in the ``ifstmt`` column to view the ``if`` statement in the code viewer.
The matching ``if`` statement is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code.
.. include:: ../reusables/vs-code-basic-instructions/note-store-quick-query.rst
About the query structure
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -133,14 +106,24 @@ To exclude ``if`` statements that have an ``else`` branch:
pass instanceof Pass and
not exists(ifstmt.getOrelse())
#. Click **Run**.
#. Re-run the query.
There are now fewer results because ``if`` statements with an ``else`` branch are no longer included.
`See this in the query console <https://lgtm.com/query/3424727946018612474/>`__
Further reading
---------------
.. include:: ../reusables/python-further-reading.rst
.. include:: ../reusables/codeql-ref-tools-further-reading.rst
.. Article-specific substitutions for the reusables used in docs/codeql/reusables/vs-code-basic-instructions
.. |language-text| replace:: Python
.. |language-code| replace:: ``python``
.. |example-url| replace:: https://github.com/saltstack/salt
.. |image-quick-query| image:: ../images/codeql-for-visual-studio-code/quick-query-tab-python.png
.. |result-col-1| replace:: The first column corresponds to the expression ``ifstmt`` and is linked to the location in the source code of the project where ``ifstmt`` occurs.

View File

@@ -3,7 +3,9 @@
Basic query for Ruby code
=========================
Learn to write and run a simple CodeQL query.
Learn to write and run a simple CodeQL query using Visual Studio Code with the CodeQL extension.
.. include:: ../reusables/vs-code-basic-instructions/setup-to-run-queries.rst
About the query
---------------
@@ -15,24 +17,14 @@ The query we're going to run performs a basic search of the code for ``if`` expr
if error
# Handle the error
Running the query
-----------------
.. include:: ../reusables/vs-code-basic-instructions/find-database.rst
#. In the main search box on LGTM.com, search for the project you want to query. For tips, see `Searching <https://lgtm.com/help/lgtm/searching>`__.
Running a quick query
---------------------
#. Click the project in the search results.
.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-1.rst
#. Click **Query this project**.
This opens the query console. (For information about using this, see `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.)
.. pull-quote::
Note
Alternatively, you can go straight to the query console by clicking **Query console** (at the top of any page), selecting **Ruby** from the **Language** drop-down list, then choosing one or more projects to query from those displayed in the **Project** drop-down list.
#. Copy the following query into the text box in the query console:
#. In the quick query tab, delete the content and paste in the following query.
.. code-block:: ql
@@ -40,37 +32,20 @@ Running the query
from IfExpr ifexpr
where
not exists(ifexpr.getThen())
not exists(ifexpr.getThen())
select ifexpr, "This 'if' expression is redundant."
LGTM checks whether your query compiles and, if all is well, the **Run** button changes to green to indicate that you can go ahead and run the query.
.. include:: ../reusables/vs-code-basic-instructions/run-quick-query-2.rst
#. Click **Run**.
.. image:: ../images/codeql-for-visual-studio-code/basic-ruby-query-results-1.png
:align: center
The name of the project you are querying, and the ID of the most recently analyzed commit to the project, are listed below the query box. To the right of this is an icon that indicates the progress of the query operation:
If any matching code is found, click a link in the ``ifexpr`` column to open the file and highlight the matching ``if`` statement.
.. image:: ../images/query-progress.png
:align: center
.. image:: ../images/codeql-for-visual-studio-code/basic-ruby-query-results-2.png
:align: center
.. pull-quote::
Note
Your query is always run against the most recently analyzed commit to the selected project.
The query will take a few moments to return results. When the query completes, the results are displayed below the project name. The query results are listed in two columns, corresponding to the two expressions in the ``select`` clause of the query. The first column corresponds to the expression ``ifexpr`` and is linked to the location in the source code of the project where ``ifexpr`` occurs. The second column is the alert message.
`Example query results <https://lgtm.com/query/4416853782037269427/>`__
.. pull-quote::
Note
An ellipsis (…) at the bottom of the table indicates that the entire list is not displayed—click it to show more results.
#. If any matching code is found, click a link in the ``ifexpr`` column to view the ``if`` statement in the code viewer.
The matching ``if`` expression is highlighted with a yellow background in the code viewer. If any code in the file also matches a query from the standard query library for that language, you will see a red alert message at the appropriate point within the code.
.. include:: ../reusables/vs-code-basic-instructions/note-store-quick-query.rst
About the query structure
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -131,14 +106,24 @@ To exclude ``if`` statements that have an ``else`` branch:
not exists(ifexpr.getThen()) and
not exists(ifexpr.getElse())
#. Click **Run**.
#. Re-run the query.
There are now fewer results because ``if`` expressions with an ``else`` branch are no longer included.
`See this in the query console <https://lgtm.com/query/4694253275631320752/>`__
Further reading
---------------
.. include:: ../reusables/ruby-further-reading.rst
.. include:: ../reusables/codeql-ref-tools-further-reading.rst
.. Article-specific substitutions for the reusables used in docs/codeql/reusables/vs-code-basic-instructions
.. |language-text| replace:: Ruby
.. |language-code| replace:: ``ruby``
.. |example-url| replace:: https://github.com/discourse/discourse
.. |image-quick-query| image:: ../images/codeql-for-visual-studio-code/quick-query-tab-ruby.png
.. |result-col-1| replace:: The first column corresponds to the expression ``ifexpr`` and is linked to the location in the source code of the project where ``ifexpr`` occurs.

View File

@@ -21,7 +21,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat
hash-consing-and-value-numbering
- :doc:`Basic query for C and C++ code <basic-query-for-cpp-code>`: Learn to write and run a simple CodeQL query using LGTM.
- :doc:`Basic query for C and C++ code <basic-query-for-cpp-code>`: Learn to write and run a simple CodeQL query.
- :doc:`CodeQL library for C and C++ <codeql-library-for-cpp>`: When analyzing C or C++ code, you can use the large collection of classes in the CodeQL library for C and C++.

View File

@@ -12,7 +12,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat
codeql-library-for-csharp
analyzing-data-flow-in-csharp
- :doc:`Basic query for C# code <basic-query-for-csharp-code>`: Learn to write and run a simple CodeQL query using LGTM.
- :doc:`Basic query for C# code <basic-query-for-csharp-code>`: Learn to write and run a simple CodeQL query.
- :doc:`CodeQL library for C# <codeql-library-for-csharp>`: When you're analyzing a C# program, you can make use of the large collection of classes in the CodeQL library for C#.

View File

@@ -13,7 +13,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat
abstract-syntax-tree-classes-for-working-with-go-programs
modeling-data-flow-in-go-libraries
- :doc:`Basic query for Go code <basic-query-for-go-code>`: Learn to write and run a simple CodeQL query using LGTM.
- :doc:`Basic query for Go code <basic-query-for-go-code>`: Learn to write and run a simple CodeQL query.
- :doc:`CodeQL library for Go <codeql-library-for-go>`: When you're analyzing a Go program, you can make use of the large collection of classes in the CodeQL library for Go.

View File

@@ -1,9 +1,16 @@
.. _codeql-for-java:
CodeQL for Java
===============
CodeQL for Java and Kotlin
==========================
Experiment and learn how to write effective and efficient queries for CodeQL databases generated from Java codebases.
Experiment and learn how to write effective and efficient queries for CodeQL databases generated from Java and Kotlin codebases.
.. include:: ../reusables/kotlin-beta-note.rst
.. pull-quote:: Enabling Kotlin support
CodeQL treats Java and Kotlin as parts of the same language, so to enable Kotlin support you should enable ``java`` as a language.
.. toctree::
:hidden:
@@ -19,7 +26,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat
working-with-source-locations
abstract-syntax-tree-classes-for-working-with-java-programs
- :doc:`Basic query for Java code <basic-query-for-java-code>`: Learn to write and run a simple CodeQL query using LGTM.
- :doc:`Basic query for Java code <basic-query-for-java-code>`: Learn to write and run a simple CodeQL query.
- :doc:`CodeQL library for Java <codeql-library-for-java>`: When analyzing Java code, you can use the large collection of classes in the CodeQL library for Java.

View File

@@ -18,7 +18,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat
abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs
data-flow-cheat-sheet-for-javascript
- :doc:`Basic query for JavaScript code <basic-query-for-javascript-code>`: Learn to write and run a simple CodeQL query using LGTM.
- :doc:`Basic query for JavaScript code <basic-query-for-javascript-code>`: Learn to write and run a simple CodeQL query.
- :doc:`CodeQL library for JavaScript <codeql-library-for-javascript>`: When you're analyzing a JavaScript program, you can make use of the large collection of classes in the CodeQL library for JavaScript.

View File

@@ -16,7 +16,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat
expressions-and-statements-in-python
analyzing-control-flow-in-python
- :doc:`Basic query for Python code <basic-query-for-python-code>`: Learn to write and run a simple CodeQL query using LGTM.
- :doc:`Basic query for Python code <basic-query-for-python-code>`: Learn to write and run a simple CodeQL query.
- :doc:`CodeQL library for Python <codeql-library-for-python>`: When you need to analyze a Python program, you can make use of the large collection of classes in the CodeQL library for Python.

View File

@@ -14,7 +14,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat
analyzing-data-flow-in-ruby
using-api-graphs-in-ruby
- :doc:`Basic query for Ruby code <basic-query-for-ruby-code>`: Learn to write and run a simple CodeQL query using LGTM.
- :doc:`Basic query for Ruby code <basic-query-for-ruby-code>`: Learn to write and run a simple CodeQL query.
- :doc:`CodeQL library for Ruby <codeql-library-for-ruby>`: When you're analyzing a Ruby program, you can make use of the large collection of classes in the CodeQL library for Ruby.

View File

@@ -70,7 +70,7 @@ For example, the following query finds all variables of type ``int`` in the prog
pt.hasName("int")
select v
`See this in the query console on LGTM.com <https://lgtm.com/query/860076406167044435/>`__. You're likely to get many results when you run this query because most projects contain many variables of type ``int``.
You're likely to get many results when you run this query because most projects contain many variables of type ``int``.
Reference types are also categorized according to their declaration scope:
@@ -87,7 +87,7 @@ For instance, this query finds all top-level types whose name is not the same as
where tl.getName() != tl.getCompilationUnit().getName()
select tl
`See this in the query console on LGTM.com <https://lgtm.com/query/4340983612585284460/>`__. This pattern is seen in many projects. When we ran it on the LGTM.com demo projects, most of the projects had at least one instance of this problem in the source code. There were many more instances in the files referenced by the source code.
You will typically see this pattern in the source code of a repository, with many more instances in the files referenced by the source code.
Several more specialized classes are available as well:
@@ -109,7 +109,7 @@ As an example, we can write a query that finds all nested classes that directly
where nc.getASupertype() instanceof TypeObject
select nc
`See this in the query console on LGTM.com <https://lgtm.com/query/8482509736206423238/>`__. You're likely to get many results when you run this query because many projects include nested classes that extend ``Object`` directly.
You're likely to get many results when you run this query because many projects include nested classes that extend ``Object`` directly.
Generics
~~~~~~~~
@@ -143,8 +143,6 @@ For instance, we could use the following query to find all parameterized instanc
pt.getSourceDeclaration() = map
select pt
`See this in the query console on LGTM.com <https://lgtm.com/query/7863873821043873550/>`__. None of the LGTM.com demo projects contain parameterized instances of ``java.util.Map`` in their source code, but they all have results in reference files.
In general, generic types may restrict which types a type parameter can be bound to. For instance, a type of maps from strings to numbers could be declared as follows:
.. code-block:: java
@@ -166,8 +164,6 @@ As an example, the following query finds all type variables with type bound ``Nu
tb.getType().hasQualifiedName("java.lang", "Number")
select tv
`See this in the query console on LGTM.com <https://lgtm.com/query/6740696080876162817/>`__. When we ran it on the LGTM.com demo projects, the *neo4j/neo4j*, *hibernate/hibernate-orm* and *apache/hadoop* projects all contained examples of this pattern.
For dealing with legacy code that is unaware of generics, every generic type has a "raw" version without any type parameters. In the CodeQL libraries, raw types are represented using class ``RawType``, which has the expected subclasses ``RawClass`` and ``RawInterface``. Again, there is a predicate ``getSourceDeclaration`` for obtaining the corresponding generic type. As an example, we can find variables of (raw) type ``Map``:
.. code-block:: ql
@@ -179,8 +175,6 @@ For dealing with legacy code that is unaware of generics, every generic type has
rt.getSourceDeclaration().hasQualifiedName("java.util", "Map")
select v
`See this in the query console on LGTM.com <https://lgtm.com/query/4032913402499547882/>`__. Many projects have variables of raw type ``Map``.
For example, in the following code snippet this query would find ``m1``, but not ``m2``:
.. code-block:: java
@@ -230,7 +224,7 @@ For example, the following query finds all expressions whose parents are ``retur
where e.getParent() instanceof ReturnStmt
select e
`See this in the query console on LGTM.com <https://lgtm.com/query/1947757851560375919/>`__. Many projects have examples of ``return`` statements with child expressions.
Many projects have examples of ``return`` statements with child expressions.
Therefore, if the program contains a return statement ``return x + y;``, this query will return ``x + y``.
@@ -244,7 +238,7 @@ As another example, the following query finds statements whose parent is an ``if
where s.getParent() instanceof IfStmt
select s
`See this in the query console on LGTM.com <https://lgtm.com/query/1989464153689219612/>`__. Many projects have examples of ``if`` statements with child statements.
Many projects have examples of ``if`` statements with child statements.
This query will find both ``then`` branches and ``else`` branches of all ``if`` statements in the program.
@@ -258,8 +252,6 @@ Finally, here is a query that finds method bodies:
where s.getParent() instanceof Method
select s
`See this in the query console on LGTM.com <https://lgtm.com/query/1016821702972128245/>`__. Most projects have many method bodies.
As these examples show, the parent node of an expression is not always an expression: it may also be a statement, for example, an ``IfStmt``. Similarly, the parent node of a statement is not always a statement: it may also be a method or a constructor. To capture this, the QL Java library provides two abstract class ``ExprParent`` and ``StmtParent``, the former representing any node that may be the parent node of an expression, and the latter any node that may be the parent node of a statement.
For more information on working with AST classes, see the :doc:`article on overflow-prone comparisons in Java <overflow-prone-comparisons-in-java>`.
@@ -278,7 +270,7 @@ For annotations, class ``Annotatable`` is a superclass of all program elements t
from Constructor c
select c.getAnAnnotation()
`See this in the query console on LGTM.com <https://lgtm.com/query/3206112561297137365/>`__. The LGTM.com demo projects all use annotations, you can see examples where they are used to suppress warnings and mark code as deprecated.
You may see examples where annotations are used to suppress warnings or to mark code as deprecated.
These annotations are represented by class ``Annotation``. An annotation is simply an expression whose type is an ``AnnotationType``. For example, you can amend this query so that it only reports deprecated constructors:
@@ -292,7 +284,7 @@ These annotations are represented by class ``Annotation``. An annotation is simp
anntp.hasQualifiedName("java.lang", "Deprecated")
select ann
`See this in the query console on LGTM.com <https://lgtm.com/query/5393027107459215059/>`__. Only constructors with the ``@Deprecated`` annotation are reported this time.
Only constructors with the ``@Deprecated`` annotation are reported this time.
For more information on working with annotations, see the :doc:`article on annotations <annotations-in-java>`.
@@ -307,7 +299,7 @@ For Javadoc, class ``Element`` has a member predicate ``getDoc`` that returns a
jdoc = f.getDoc().getJavadoc()
select jdoc
`See this in the query console on LGTM.com <https://lgtm.com/query/6022769142134600659/>`__. You can see this pattern in many projects.
You can see this pattern in many projects.
Class ``Javadoc`` represents an entire Javadoc comment as a tree of ``JavadocElement`` nodes, which can be traversed using member predicates ``getAChild`` and ``getParent``. For instance, you could edit the query so that it finds all ``@author`` tags in Javadoc comments on private fields:
@@ -321,8 +313,6 @@ Class ``Javadoc`` represents an entire Javadoc comment as a tree of ``JavadocEle
at.getParent+() = jdoc
select at
`See this in the query console on LGTM.com <https://lgtm.com/query/2510220694395289111/>`__. None of the LGTM.com demo projects uses the ``@author`` tag on private fields.
.. pull-quote::
Note
@@ -349,7 +339,7 @@ For example, the following query finds methods with a `cyclomatic complexity <ht
mc.getCyclomaticComplexity() > 40
select m
`See this in the query console on LGTM.com <https://lgtm.com/query/6566950741051181919/>`__. Most large projects include some methods with a very high cyclomatic complexity. These methods are likely to be difficult to understand and test.
Most large projects include some methods with a very high cyclomatic complexity. These methods are likely to be difficult to understand and test.
Call graph
----------
@@ -369,8 +359,6 @@ We can use predicate ``Call.getCallee`` to find out which method or constructor
m.hasName("println")
select c
`See this in the query console on LGTM.com <https://lgtm.com/query/5861255162551917595/>`__. The LGTM.com demo projects all include many calls to methods of this name.
Conversely, ``Callable.getAReference`` returns a ``Call`` that refers to it. So we can find methods and constructors that are never called using this query:
.. code-block:: ql
@@ -381,7 +369,7 @@ Conversely, ``Callable.getAReference`` returns a ``Call`` that refers to it. So
where not exists(c.getAReference())
select c
`See this in the query console on LGTM.com <https://lgtm.com/query/7261739919657747703/>`__. The LGTM.com demo projects all appear to have many methods that are not called directly, but this is unlikely to be the whole story. To explore this area further, see ":doc:`Navigating the call graph <navigating-the-call-graph>`."
Codebases often have many methods that are not called directly, but this is unlikely to be the whole story. To explore this area further, see ":doc:`Navigating the call graph <navigating-the-call-graph>`."
For more information about callables and calls, see the :doc:`article on the call graph <navigating-the-call-graph>`.

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