Compare commits

..

611 Commits

Author SHA1 Message Date
Dave Bartolomeo
85cfb83f32 Move JavaScript dbscheme and upgrades into new codeql/javascript-base pack 2024-10-02 14:44:49 -04:00
Geoffrey White
f7db47b771 Merge pull request #17588 from geoffw0/loc2
Rust: Improve lines-of-code counts.
2024-10-02 18:13:36 +01:00
Geoffrey White
0b6ec4624e Rust: Autoformat. 2024-10-02 17:05:01 +01:00
Geoffrey White
d6848f5c5d Rust: Apparently a doc comment here was illegal. 2024-10-02 17:00:28 +01:00
Geoffrey White
01abcf8537 Rust: Use just end locations for now, to avoid all false positive lines caused by attached comments. 2024-10-02 16:54:02 +01:00
Geoffrey White
8c87b66bea Rust: Add more test cases for comments. 2024-10-02 16:52:19 +01:00
Tom Hvitved
d6415cd0c8 Merge pull request #17642 from hvitved/rust/unused-variable
Rust: Implement `UnusedVariable.ql`
2024-10-02 15:41:24 +02:00
Tom Hvitved
3a1f6efce4 Address review comments 2024-10-02 13:37:24 +02:00
Geoffrey White
8243f87179 Rust: Modify the exclusion as suggested in comments. 2024-10-02 11:38:29 +01:00
Tom Hvitved
fb9ec2423c Rust: Implement UnusedVariable.ql 2024-10-02 11:22:32 +02:00
Tom Hvitved
3fa52ad680 Merge pull request #17633 from hvitved/rust/cfg-fixes
Rust: More CFG modelling
2024-10-02 11:21:53 +02:00
Tom Hvitved
9c7216fe4f Rust: Add another CFG test 2024-10-02 10:59:26 +02:00
Tom Hvitved
69e0ad0181 Rust: Refactor CFG implementation for loops 2024-10-02 10:55:52 +02:00
Calum Grant
8b536f54fd Merge pull request #17481 from github/calumgrant/bmn/uninitialized-local
C++: Remove FPs from cpp/uninitialized-local when encountered extraction errors
2024-10-02 09:29:15 +01:00
Calum Grant
d3695dce4d C++: Add change note 2024-10-02 08:14:23 +01:00
Tom Hvitved
8f0b7f0969 Rust: Use propagatesAbnormal in two places 2024-10-01 21:49:08 +02:00
Tom Hvitved
c4eafb2cf3 Rust: Skip ParenExprs in the CFG 2024-10-01 21:26:49 +02:00
Tom Hvitved
8b66dc16ad Rust: Fix CFG for labelled block expressions 2024-10-01 21:03:36 +02:00
Tom Hvitved
e8cb3490e6 Rust: Refine deadEnd consistency check 2024-10-01 21:02:55 +02:00
Tom Hvitved
85957767c9 Rust: Fix CFG for while let loops 2024-10-01 21:02:17 +02:00
Tom Hvitved
071076875c Rust: Make more CFG nodes leaves 2024-10-01 21:01:56 +02:00
Tom Hvitved
26c69b8f8a Rust: Add more CFG tests 2024-10-01 21:01:49 +02:00
Tom Hvitved
bbd0aa929f Rust: Add more missing CFG trees 2024-10-01 21:01:26 +02:00
Tom Hvitved
17770af491 Rust: Account for let statement else blocks in deadEnd 2024-10-01 21:00:39 +02:00
Tom Hvitved
a507854288 Rust: Fix bug in BooleanCompletion.isValidForSpecific0 2024-10-01 21:00:33 +02:00
Tom Hvitved
8c1fd8fa7a Rust: Implement CFG for ForExprs 2024-10-01 21:00:09 +02:00
Tom Hvitved
f3e3734424 Rust: Implement CFG for WhileExprs 2024-10-01 20:59:41 +02:00
Tom Hvitved
5444a5bf8a Rust: Extend while and for CFG tests 2024-10-01 20:59:13 +02:00
Geoffrey White
3a54c10f36 Rust: For now exclude top-level AST elements from LOC counts. This is not ideal. 2024-10-01 17:35:30 +01:00
Tom Hvitved
5fb61b0304 Merge pull request #17606 from hvitved/rust/variables 2024-10-01 18:13:32 +02:00
Ian Lynagh
6af5afc184 Merge pull request #17634 from igfoo/igfoo/implicit_param_name
Java: Add a test for parameter names
2024-10-01 17:03:18 +01:00
Calum Grant
cd1f10cdea C++: Reinstate accidentally-deleted comment 2024-10-01 16:15:24 +01:00
Geoffrey White
74826032ef Merge branch 'main' into loc2 and accept new test results. 2024-10-01 16:10:39 +01:00
Calum Grant
a9b3c0d91b C++: Address review comments 2024-10-01 15:47:12 +01:00
Ian Lynagh
323b7cb96f Java: Follow change of implicit parameter names 2024-10-01 15:06:45 +01:00
Ian Lynagh
901f756c69 Java: Add a test for parameter names 2024-10-01 15:06:42 +01:00
Chris Smowton
01c9509741 Merge pull request #17628 from smowton/smowton/admin/go-vendor-dir-extraction-option
Go: add extractor option for vendor-directory extraction
2024-10-01 14:47:42 +01:00
Anders Schack-Mulligen
6081ba5902 Merge pull request #17604 from aschackmull/java/neutral-overrides
Java/C#: Add overrides to the interpretation of neutral MaD models.
2024-10-01 14:55:54 +02:00
Tom Hvitved
91e26d0f44 Rust: Add another variable test 2024-10-01 13:45:58 +02:00
Tom Hvitved
a172063e6a Rust: Document VariableOrAccessCand 2024-10-01 13:38:18 +02:00
Calum Grant
fe00c8819d C++: Fix formatting 2024-10-01 11:26:47 +01:00
Chris Smowton
cb0b388345 Merge pull request #17630 from smowton/smowton/admin/deduplicate-tests
Go: deduplicate integration tests
2024-10-01 11:08:00 +01:00
Calum Grant
4712ae1cfc C++: Use refactored isFirstAllocatorCallArgument() 2024-10-01 11:01:51 +01:00
Calum Grant
59a77d70c0 C++: Use Function::hasErrors in queries 2024-10-01 11:01:23 +01:00
Calum Grant
4b5aa1497b C++: Implement Function::hasErrors() 2024-10-01 11:00:44 +01:00
Chris Smowton
d689db23d8 Warn on use of old option 2024-10-01 10:43:28 +01:00
Calum Grant
60abea17e6 C++: Test for cpp/uninitialized-local 2024-10-01 10:32:17 +01:00
Jeroen Ketema
66d156d386 Merge pull request #17608 from jketema/macro-expansion-tests
C++: Add more macro expansion tests
2024-10-01 11:19:49 +02:00
Tom Hvitved
b0efffd8f0 Rust: AST support for variables 2024-10-01 10:10:08 +02:00
Tom Hvitved
a282efc43e Rust: Add inline test expectations library 2024-10-01 09:50:05 +02:00
Tom Hvitved
1d6626c821 Rust: Implement IdentPat.toString() 2024-10-01 08:42:26 +02:00
Jeroen Ketema
2427227b84 Merge pull request #17611 from microsoft/brodes/wcharcharconversion_false_positives_upstream5
Brodes/wcharcharconversion false positives upstream5
2024-10-01 08:00:51 +02:00
Angela P Wen
204e4c5bb0 Merge pull request #17631 from github/post-release-prep/codeql-cli-2.19.1
Post-release preparation for codeql-cli-2.19.1
2024-09-30 13:47:39 -07:00
github-actions[bot]
e97878ed63 Post-release preparation for codeql-cli-2.19.1 2024-09-30 19:49:00 +00:00
Chris Smowton
be389b4c19 Go: deduplicate integration tests 2024-09-30 19:54:14 +01:00
Angela P Wen
7dcdd7429f Merge pull request #17629 from github/release-prep/2.19.1
Release preparation for version 2.19.1
2024-09-30 11:04:41 -07:00
github-actions[bot]
455c8c5953 Release preparation for version 2.19.1 2024-09-30 17:59:48 +00:00
Chris Smowton
c9d6c80913 Log when vendor dir extraction is active 2024-09-30 18:44:20 +01:00
Chris Smowton
684aedf6aa Golang vendor dir extraction: add extractor option 2024-09-30 18:24:49 +01:00
REDMOND\brodes
c496503053 Formatting. 2024-09-30 11:23:08 -04:00
REDMOND\brodes
eeddb176f8 Merge branch 'brodes/wcharcharconversion_false_positives_upstream5' of https://github.com/microsoft/codeql into brodes/wcharcharconversion_false_positives_upstream5 2024-09-30 11:20:20 -04:00
REDMOND\brodes
162519185d Removing unnecessary bracket/singleton set literal. 2024-09-30 11:19:31 -04:00
Ben Rodes
9e9469f3ca Update cpp/ql/src/change-notes/2024-09-26-wcharcharconversion-false-positives.md
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2024-09-30 11:17:48 -04:00
REDMOND\brodes
318e75c094 Changing name of predicate to be clearer, and removing an unused parameter. 2024-09-30 11:10:28 -04:00
REDMOND\brodes
c91f7f4918 Altering exists predicate ordering to be clearer. 2024-09-30 11:07:09 -04:00
REDMOND\brodes
31324fc778 Altering ordering for exists statement to be clearer. 2024-09-30 11:05:38 -04:00
REDMOND\brodes
51e787b316 Switching to looking for explicit declaration of unsigned char, to avoid cases where unsigned char is the default char width for char. 2024-09-30 11:02:43 -04:00
REDMOND\brodes
c4737c7fbb Changing from hasIntermediateType to getABaseType. 2024-09-30 10:58:45 -04:00
Tom Hvitved
70b4ecf0a5 Merge pull request #17624 from github/aibaars/rust-comments
Rust: extract comments
2024-09-30 16:58:25 +02:00
REDMOND\brodes
338ab96593 Correct comment. 2024-09-30 10:46:39 -04:00
Tom Hvitved
938e962d79 Merge remote-tracking branch 'upstream/main' into aibaars/rust-comments 2024-09-30 16:42:22 +02:00
Anders Schack-Mulligen
d0831ebd5a Merge pull request #17625 from aschackmull/java/collection-neutrals
Java: Minor model tweak and comment fix.
2024-09-30 16:29:54 +02:00
Anders Schack-Mulligen
5c4b4d644a C#: Accept test changes. 2024-09-30 16:27:50 +02:00
Tom Hvitved
52894f5b6a Merge pull request #17627 from hvitved/rust/accept-cfg-inconsistencies 2024-09-30 16:00:58 +02:00
Anders Schack-Mulligen
222ae6ad2d Java: Add a neutral for Comparable.compareTo 2024-09-30 15:51:48 +02:00
Anders Schack-Mulligen
fcb677e84d Java: Add a neutral for Collection.remove. 2024-09-30 15:46:43 +02:00
Anders Schack-Mulligen
38818f3cd2 Java: Adjust Set.clear model to apply to overrides. 2024-09-30 15:46:42 +02:00
Tom Hvitved
2018b6361d Rust: Accept CFG inconsistencies 2024-09-30 15:45:15 +02:00
Arthur Baars
d3c50727ed Rust: exclude Comment nodes from lines of code counts 2024-09-30 15:39:00 +02:00
Arthur Baars
45d3d381f5 Rust: test cases for comments 2024-09-30 15:38:59 +02:00
Arthur Baars
ef3f730d32 Rust: extract comment tokens 2024-09-30 15:38:58 +02:00
Arthur Baars
fd459be165 Rust: add Comment to schema 2024-09-30 15:38:54 +02:00
Tom Hvitved
3a210b77f9 Merge pull request #17626 from hvitved/rust/more-cfg-tests 2024-09-30 15:37:55 +02:00
Tom Hvitved
c3311e52a6 Merge pull request #17623 from hvitved/rust/labelled-block 2024-09-30 15:33:55 +02:00
Anders Schack-Mulligen
a8f55d93cb C#: Add overrides to the interpretation of neutral MaD models. 2024-09-30 15:23:27 +02:00
Anders Schack-Mulligen
0459d136d3 Java: Remove neutral model for Object.toString. 2024-09-30 15:17:21 +02:00
Tom Hvitved
2e7e26b638 Rust: Add more CFG tests 2024-09-30 15:15:14 +02:00
Anders Schack-Mulligen
1f95fa10fb Java: Fix comment re. neutrals and WithoutElement.
The remove methods should not have been in this section, as they're
plain neutrals.
2024-09-30 15:08:56 +02:00
Tom Hvitved
5ae669937c Rust: Add labelled block example 2024-09-30 14:47:13 +02:00
Tamás Vajk
752502ba76 Merge pull request #17619 from tamasvajk/text-file-archiving-warning
C#: reduce extraction message severity for missing text files
2024-09-30 14:07:45 +02:00
Anders Schack-Mulligen
ec0bd4494c Java: Add overrides to the interpretation of neutral MaD models. 2024-09-30 13:11:49 +02:00
Tamas Vajk
29948e4c0b C#: reduce extraction message severity for missing text files 2024-09-30 12:31:07 +02:00
Michael Nebel
6f74387600 Merge pull request #17521 from michaelnebel/modelgen/moreimprovements
C#/Java: Content based model generation improvements.
2024-09-30 11:22:30 +02:00
Tom Hvitved
4513643a0f Merge pull request #17617 from hvitved/rust/extraction-consistency
Rust: Add extraction error consistency query
2024-09-30 11:06:34 +02:00
Tom Hvitved
3e77dd8b6b Rust: Fix extraction errors 2024-09-30 10:36:56 +02:00
Tom Hvitved
bafef791f7 Rust: Add extraction error consistency query 2024-09-30 10:28:24 +02:00
Anders Schack-Mulligen
a017f92b78 Merge pull request #17579 from aschackmull/java/type-sanitizers
Java: Add more type-based sanitizers.
2024-09-30 10:07:06 +02:00
Tom Hvitved
8a1b4501dd Merge pull request #17602 from hvitved/rust/cfg-prune-bool-literal
Rust: Prune CFG for obviously impossible `true/false` edges
2024-09-30 10:05:03 +02:00
Anders Schack-Mulligen
b0ed47c277 Merge pull request #17605 from aschackmull/java/stringbuilder-neutrals
Java: Add a couple of neutrals
2024-09-30 10:03:41 +02:00
Michael Nebel
baae8d0bb2 Shared: Address model generator review comments. 2024-09-30 09:12:30 +02:00
Jeroen Ketema
e73d1c7b76 C++: Add more macro expansion tests 2024-09-28 22:32:36 +02:00
Owen Mansel-Chan
654d97013f Merge pull request #17607 from owen-mc/go/add-comments-about-interface-methods-from-embedded-interfaces
Go: Add comments noting methods from embedded interfaces are already included
2024-09-28 13:49:50 +01:00
Chris Smowton
ca68aaa0de Remove test code 2024-09-27 19:07:00 +01:00
REDMOND\brodes
b73fe0ba0a Adding change log 2024-09-27 12:41:45 -04:00
REDMOND\brodes
92c8d39ba3 Updating expected file, false positives now resolved. 2024-09-27 12:39:50 -04:00
REDMOND\brodes
cc24f1ed9f Modifications to the query to address false positives. 2024-09-27 12:38:22 -04:00
REDMOND\brodes
26e58532ee Adding tests and updated expected file with false positives to correct. 2024-09-27 12:37:09 -04:00
Owen Mansel-Chan
796db77104 Add comments noting methods from embedded interfaces are already included 2024-09-27 15:03:09 +01:00
Anders Schack-Mulligen
fb630d266e Java: Add a couple of neutrals 2024-09-27 15:24:06 +02:00
Tom Hvitved
90a8bef64c Rust: Run codegen 2024-09-27 13:39:15 +02:00
Ian Lynagh
7de1182f92 Merge pull request #17599 from igfoo/igfoo/constrs
Kotlin: Fix the return type for lambda constructors
2024-09-27 12:38:50 +01:00
Tom Hvitved
dc4160b24a Rust: Prune CFG for impossible true/false edges 2024-09-27 13:37:29 +02:00
Tom Hvitved
bf58bdd2bd Rust: Update CFG tests 2024-09-27 13:35:14 +02:00
Tom Hvitved
431b33a274 Rust: Implement LiteralExpr::toString() 2024-09-27 13:33:25 +02:00
Tom Hvitved
97ead6f462 Merge pull request #17560 from hvitved/codegen/remove-cached
Codegen: Do not cache injectors/projectors in `Synth` module
2024-09-27 13:17:02 +02:00
Ian Lynagh
2a5b48930a Kotlin: Fix the return type for lambda constructors 2024-09-27 11:21:40 +01:00
Ian Lynagh
08be35fc2c Kotlin: Add a test for constructors 2024-09-27 11:21:23 +01:00
Michael Nebel
0b39c5b982 C#/Java: Update model generator expected output. 2024-09-27 09:22:29 +02:00
Michael Nebel
80497f551e Shared: Only make unlifted models in case the API itself is relevant. 2024-09-27 09:22:25 +02:00
Michael Nebel
3d1a403655 C#: Add example of content based summary on private method. 2024-09-27 09:22:20 +02:00
Michael Nebel
ccadfa134e Shared: Update the model generator script to allow execution of the mixed model generator queries. 2024-09-27 09:22:15 +02:00
Michael Nebel
8310faa2e9 C#/Java: Add a query that uses both content based and non-content based model generation. 2024-09-27 09:22:11 +02:00
Owen Mansel-Chan
fdff209938 Merge pull request #17505 from owen-mc/go/inheritance-tests
Go: Add tests for model inheritance and fix bug in promoted methods
2024-09-26 16:42:25 +01:00
Calum Grant
8e85f24c95 Merge pull request #17553 from github/calumgrant/bmn/wrong-number-of-format-arguments
C++: Remove FPs in cpp/wrong-number-format-arguments due to BMN
2024-09-26 15:01:23 +01:00
Calum Grant
8967989c7b C++: Rename change-note 2024-09-26 13:39:46 +01:00
Tom Hvitved
7c473c38c0 Merge pull request #17585 from hvitved/shared/cfg-scope-no-first-consistency
Shared: Add CFG consistency check for scopes with missing entry points
2024-09-26 14:05:08 +02:00
Calum Grant
dcb75f490f Update cpp/ql/src/change-notes/2024-09-26-wrong-number-format-arguments
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2024-09-26 13:05:06 +01:00
Calum Grant
8045440d00 Update cpp/ql/lib/semmle/code/cpp/models/interfaces/FormattingFunction.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2024-09-26 13:04:52 +01:00
Rasmus Wriedt Larsen
7c32efc218 Merge pull request #17203 from RasmusWL/threat-models
Python: Add support for threat models
2024-09-26 13:15:46 +02:00
Rasmus Wriedt Larsen
381ea93ec3 Merge pull request #17424 from RasmusWL/active-threat-model-source
Go/Java/C#: Rename `ThreatModelFlowSource` to `ActiveThreatModelSource`
2024-09-26 13:08:17 +02:00
Michael Nebel
a128383760 C#/Java: Add some dfc-generated test cases. 2024-09-26 13:01:01 +02:00
Michael Nebel
2a5dc204fb Shared: Add dfc as a valid model origin. 2024-09-26 13:00:57 +02:00
Michael Nebel
9a923d62ad C#/Java: Updated expected test output. 2024-09-26 13:00:52 +02:00
Michael Nebel
e70297a7bc Shared: Content based models is now printed with dfc-generated provenance. 2024-09-26 13:00:39 +02:00
Arthur Baars
d7fb7ab551 Merge pull request #17592 from github/aibaars/cargo-fmt
Rust: run cargo fmt
2024-09-26 12:57:15 +02:00
Michael Nebel
53c20ccaeb Shared: Some model generator re-factoring. 2024-09-26 12:55:01 +02:00
Michael Nebel
0cd4ccb790 C#/Java: Update model generator expected test output. 2024-09-26 12:49:18 +02:00
Michael Nebel
b041829569 Shared: steps in synthetic path chains should just mention the same synthetic fields. 2024-09-26 12:49:07 +02:00
Arthur Baars
6777a34dfb Rust: run cargo fmt 2024-09-26 12:40:25 +02:00
Geoffrey White
caca4950e6 Rust: Revert the change to FileSystem.qll. 2024-09-26 11:10:32 +01:00
Geoffrey White
7b3960844d Merge pull request #17589 from geoffw0/missing2
Rust: Repair rust/diagnostics/unextracted-elements
2024-09-26 11:03:03 +01:00
Michael Nebel
aae8660acc C#/Java: Add some examples of missing synthetic field element flow. 2024-09-26 12:00:29 +02:00
Michael Nebel
58513cadbf C#/Java: Add model generator test examples. 2024-09-26 12:00:25 +02:00
Michael Nebel
6cd548f410 Shared: Only exclude API and parameter combinations where we could get more than three summaries. 2024-09-26 12:00:04 +02:00
Rasmus Wriedt Larsen
431a1af628 Merge branch 'main' into threat-models 2024-09-26 11:44:24 +02:00
Chris Smowton
76914c40c9 Merge pull request #17591 from github/smowton/admin/java-23-change-note
Add change note for Java 23 support
2024-09-26 10:14:21 +01:00
Tom Hvitved
f389a889ad Exclude consistency output from .gitignore files 2024-09-26 11:09:54 +02:00
Tom Hvitved
24f39ccae2 Rust: Weaken scopeNoFirst check 2024-09-26 11:09:52 +02:00
Tom Hvitved
a3ad6f5697 Ruby: Weaken scopeNoFirst check 2024-09-26 11:07:15 +02:00
Michael Nebel
dd993c3900 Merge pull request #17509 from michaelnebel/modelgen/parammodule
C#/Java: Re-factor the model generator to be a parameterized module.
2024-09-26 10:57:16 +02:00
Calum Grant
9b5c9af489 C++: Add change note 2024-09-26 09:31:45 +01:00
Calum Grant
7f2d485ae9 C++: Update comment 2024-09-26 09:31:43 +01:00
Calum Grant
c2871f4def Update cpp/ql/lib/semmle/code/cpp/Function.qll
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2024-09-26 09:31:42 +01:00
Calum Grant
4a14a3cacb Update cpp/ql/lib/semmle/code/cpp/models/interfaces/FormattingFunction.qll
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2024-09-26 09:31:40 +01:00
Calum Grant
0ad2e193e5 C++: Update test case 2024-09-26 09:31:18 +01:00
Calum Grant
31684d2548 C++: Remove FPs in cpp/wrong-number-format-arguments due to BMN 2024-09-26 09:27:59 +01:00
Calum Grant
6a0212ea44 C++: Add regression test 2024-09-26 09:27:51 +01:00
Michael Nebel
297d32180c Merge pull request #17582 from michaelnebel/csharp/attributecollectionsinks
C#: `AttributeCollection` is no longer considered a HTML sink.
2024-09-26 09:17:31 +02:00
Chris Smowton
ba5be80814 Typo 2024-09-25 21:32:52 +01:00
Chris Smowton
2c9488e475 Add change note for Java 23 support 2024-09-25 21:32:24 +01:00
Geoffrey White
f8ce11b3a7 Rust: Improve File.getNumberOfLinesOfCode(). 2024-09-25 16:42:29 +01:00
Geoffrey White
7da2845cad Rust: Uncomment two lines from the test that should now behave deterministically. 2024-09-25 16:42:28 +01:00
Ian Lynagh
a9ecb26885 Merge pull request #17555 from igfoo/igfoo/kotlin2.1
Add support for Kotlin 2.1.0-Beta1
2024-09-25 16:25:55 +01:00
Geoffrey White
bc83106dd8 Rust: Repair rust/diagnostics/unextracted-elements. 2024-09-25 16:11:31 +01:00
Erik Krogh Kristensen
6a184e0c2e Merge pull request #17587 from 5idg5/users/js-dom-xss-tst-file-id-conflict-fix
Resolve id conflict with XssWithAdditionalSources.ql
2024-09-25 17:06:20 +02:00
Michael Nebel
1dcc6ac2b1 C#: Address review comments. 2024-09-25 17:06:19 +02:00
Tom Hvitved
1bd504bf61 C#: Restrict CfgScope 2024-09-25 16:43:15 +02:00
Tom Hvitved
ce2d959b7e Shared: Add CFG consistency check for scopes with missing entry points 2024-09-25 16:43:00 +02:00
Geoffrey White
8f1c1a8399 Revert "Rust: remove queries that no longer work"
This reverts commit e19bca0de8.
2024-09-25 15:33:21 +01:00
Jeroen Ketema
0520fc2d9f Merge pull request #17583 from jketema/rm-inline
C++: Remove `inline` pragma from sink
2024-09-25 16:30:30 +02:00
Ian Lynagh
a6fce19b0c Kotlin: Fix build with 2.1.0-Beta1 2024-09-25 15:23:35 +01:00
Ian Lynagh
5a03c35e9c Kotlin: Add 2.1.0-Beta1 2024-09-25 15:23:34 +01:00
Ian Lynagh
f193084f9f Kotlin: Add 2.1.0-Beta1 jars 2024-09-25 15:23:33 +01:00
Ian Lynagh
a8cad4963e Kotlin: 2.1.0 is supported 2024-09-25 15:23:31 +01:00
Sid Gawri
e8c68fff7f resolve id conflict with dom based xss test ql 2024-09-25 10:01:59 -04:00
Felicity Chapman
85cc596041 Merge pull request #17586 from github/felicitymay-patch-1
Fix link to change logs on landing page
2024-09-25 14:40:56 +01:00
Jeroen Ketema
7289476c80 Merge pull request #17576 from jketema/formatting
C++: Do not wrap quoted text to the next line
2024-09-25 15:32:16 +02:00
Felicity Chapman
53e33d3ef3 Fix link to change logs on landing page 2024-09-25 14:28:09 +01:00
Felicity Chapman
0baa9e9ac1 Merge pull request #17580 from github/felicitymay-fix-dropdown-links
Revert changes that made the links in the drop-down on CodeQL docs site relative
2024-09-25 14:16:14 +01:00
Tom Hvitved
90869ec96a Merge pull request #17558 from hvitved/rust/cfg-consistency-queries
Rust: Enable CFG consistency checks
2024-09-25 15:14:44 +02:00
Tom Hvitved
79620c1a89 Address review comment 2024-09-25 14:18:44 +02:00
Michael Nebel
af80797eda C#: Add change note. 2024-09-25 14:13:06 +02:00
Michael Nebel
e89a47f2f5 C#: Update XSS expected test output. 2024-09-25 14:13:03 +02:00
Michael Nebel
d00e27916d C#: No longer consider attribute collections as HTML sinks. 2024-09-25 14:12:59 +02:00
Michael Nebel
28c48fb471 C#: Add Xss attribute collection test example and update expected output. 2024-09-25 14:12:55 +02:00
Jeroen Ketema
0ee1383732 C++: Remove inline pragma from sink 2024-09-25 14:04:31 +02:00
Anders Schack-Mulligen
cc63abf0af Merge pull request #17578 from aschackmull/cpp/fix-inline-sink2
Cpp: Replace sink inlining with a forward scan from source.
2024-09-25 13:54:48 +02:00
Arthur Baars
f57dd0a596 Merge pull request #17552 from github/aibaars/diagnostics
Rust: extract parse errors as diagnostics
2024-09-25 13:15:24 +02:00
Felicity Chapman
329c3c7c56 Make links in drop-down absolute 2024-09-25 10:59:22 +01:00
Owen Mansel-Chan
0ae10ece39 Merge pull request #17571 from jsoref/issue-17570
Downgrade IncorrectIntegerConversionQuery precision to high
2024-09-25 09:58:43 +01:00
Tom Hvitved
cbc2389493 Rust: Accept CFG inconsistencies 2024-09-25 10:56:46 +02:00
Tom Hvitved
d299380a5a Rust: Enable CFG consistency checks 2024-09-25 10:56:44 +02:00
Tom Hvitved
f428fdc57c Rust: Run codegen 2024-09-25 10:55:18 +02:00
Tom Hvitved
8c956e8276 Rust: Add LogicalOperation.qll 2024-09-25 10:55:16 +02:00
Tom Hvitved
3bd5c6e445 Rust: Implement {BinaryExpr,PrefixExpr}.toString() 2024-09-25 10:55:15 +02:00
Tom Hvitved
1fb9835f23 Merge pull request #17557 from hvitved/rust/cfg-improvements
Rust: CFG improvements
2024-09-25 10:54:49 +02:00
Anders Schack-Mulligen
aaecb9bb7a Java: Add more type-based sanitizers. 2024-09-25 10:38:17 +02:00
Anders Schack-Mulligen
3a1b618a74 Cpp: Replace sink inlining with a forward scan from source. 2024-09-25 10:28:23 +02:00
Jeroen Ketema
29061a08ad C++: Do not wrap quoted text to the next line
Wrapping breaks the highlighting in VSCode, making the QLDoc
difficult to read.
2024-09-25 09:43:05 +02:00
Tom Hvitved
6e493f2baa Address review comments 2024-09-25 09:09:29 +02:00
Josh Soref
a9e07a88af Downgrade IncorrectIntegerConversionQuery precision to high
`very-high` implies near 0 false positives and we have run into a number and an entire class

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2024-09-24 22:08:00 -04:00
Owen Mansel-Chan
ea4f9cad3c Mark some test results as SPURIOUS 2024-09-24 22:04:50 +01:00
Chris Smowton
590e93d8ed Merge pull request #17360 from smowton/smowton/admin/go-function-pretty-printer
Go: Expose whether functions are variadic in their pp() output
2024-09-24 21:47:50 +01:00
Owen Mansel-Chan
bcb718ac77 Add change note 2024-09-24 21:39:49 +01:00
Arthur Baars
5714811071 Rust: fix panic when the last character in a range is multi-byte 2024-09-24 19:26:02 +02:00
Chris Smowton
d673d24ca6 Revise notation to more closely resemble real Go 2024-09-24 17:22:26 +01:00
Chris Smowton
11755482e4 Update test expectation (now signature types pretty-print indicating if they are variadic) 2024-09-24 17:18:10 +01:00
Chris Smowton
40035a0b62 Improve pretty-printer 2024-09-24 17:18:09 +01:00
Chris Smowton
4d3a140dd7 Expose whether functions are variadic in their pp() output 2024-09-24 17:18:08 +01:00
Owen Mansel-Chan
73209638e3 Improve comments in test library 2024-09-24 16:41:10 +01:00
Arthur Baars
1953e4f971 Rust: handle UTF-8 decoding errors 2024-09-24 17:34:33 +02:00
Arthur Baars
37f264df74 Rust: correct line and column numbers in printed error messages 2024-09-24 17:34:32 +02:00
Arthur Baars
ca2b8ef6c0 Apply suggestions from code review
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2024-09-24 17:34:31 +02:00
Arthur Baars
9b8cbdad49 Add QLDoc to Diagnostics.qll 2024-09-24 17:34:30 +02:00
Arthur Baars
c596205416 Rust: add some more diagnostics queries 2024-09-24 17:34:29 +02:00
Arthur Baars
bdb4d89f9f Rust: add Diagnostics.qll 2024-09-24 17:34:27 +02:00
Arthur Baars
b04abc09f0 Rust: extract syntax errors 2024-09-24 17:34:26 +02:00
Owen Mansel-Chan
b0caabac86 Also update QL tests 2024-09-24 16:25:55 +01:00
Owen Mansel-Chan
6e428d5083 Fix bug where some methods were inappropriately promoted 2024-09-24 16:25:53 +01:00
Owen Mansel-Chan
0255edf524 Remove tests for sources and sinks
This is redundant given that we test for paths, and for a path
we need the source, step and sink methods to be modeled.
2024-09-24 16:25:49 +01:00
Owen Mansel-Chan
afa4b6dd4a Make paths test an inline expectations test 2024-09-24 16:23:33 +01:00
Owen Mansel-Chan
5490f3a957 Add tests for interface embedding interface 2024-09-24 16:23:31 +01:00
Owen Mansel-Chan
279800ea62 Use shorter naming scheme for types 2024-09-24 16:23:26 +01:00
Ian Lynagh
4dbb15ddda Merge pull request #17503 from igfoo/igfoo/fields
Java/Kotlin: Deprecate Field.getSourceDeclaration(), Field.isSourceDeclaration()
2024-09-24 15:15:21 +01:00
Taus
8c015b0784 Merge pull request #17305 from Kwstubbs/CORSMiddleware-Starlette
Python: Add Support for CORS Middlewares
2024-09-24 15:51:49 +02:00
Arthur Baars
47953339db Merge pull request #17543 from github/aibaars/rust-gen-extractor
Rust: generate the extractor
2024-09-24 15:47:28 +02:00
Michael Nebel
e6085759ae Shared: Put the content of CaptureSummaryFlowQuery into the shared library code. 2024-09-24 15:46:44 +02:00
Michael Nebel
fd45d2dcbb Shared: Move the model generator implementation to an internal folder. 2024-09-24 15:27:29 +02:00
Michael Nebel
22c2522aac Shared: Make a ContentSensitive module with predicates and classes related to content flow. 2024-09-24 15:16:16 +02:00
Ian Lynagh
9b8152a44b Java: Add up/downgrade scripts 2024-09-24 14:06:56 +01:00
Ian Lynagh
76662a6002 Java: Add changenote for deprecation of Field.getSourceDeclaration() and Field.isSourceDeclaration() 2024-09-24 14:06:55 +01:00
Ian Lynagh
bda779a58d Java: Deprecate Field.getSourceDeclaration() and Field.isSourceDeclaration()
Also follows the removal of the sourceid column of fields.
2024-09-24 14:06:54 +01:00
Ian Lynagh
0be52f9660 Kotlin: Follow removal of sourceid column of the fields relation 2024-09-24 14:06:53 +01:00
Ian Lynagh
300864a38b Java: dbscheme: Remove sourceid column of fields/5
It was always the same as the id column.
2024-09-24 14:06:53 +01:00
Tom Hvitved
5b45d36610 Merge pull request #17300 from hvitved/dataflow/node-ex-cached
Data flow: Cache `TNodeEx`
2024-09-24 15:04:35 +02:00
Tom Hvitved
d3368be94a Swift: Run codegen 2024-09-24 14:42:37 +02:00
Tom Hvitved
c1f3e7389f Rust: Run codegen 2024-09-24 14:42:04 +02:00
Tom Hvitved
062127b42e Codegen: Do not cache injectors/projectors in Synth module 2024-09-24 14:41:20 +02:00
Tom Hvitved
300fdc344d Go: Update expected test output 2024-09-24 14:21:42 +02:00
Tom Hvitved
6a11120e50 Address review comments 2024-09-24 14:21:40 +02:00
Tom Hvitved
16925355a8 Data flow: Cache TNodeEx 2024-09-24 14:21:39 +02:00
Tom Hvitved
f287216060 Update expected test output 2024-09-24 14:21:38 +02:00
Tom Hvitved
37490de4a2 Data flow: Remove Boolean column from TNodeImplicitRead 2024-09-24 14:21:37 +02:00
Owen Mansel-Chan
6a67bd52a9 Add tests for MaD inheritance 2024-09-24 13:21:05 +01:00
Arthur Baars
d14e77ba48 Address comments 2024-09-24 14:09:23 +02:00
Tom Hvitved
8d8bbd5b12 Rust: Run codegen 2024-09-24 13:25:57 +02:00
Tom Hvitved
5f3663018e Rust: Remove spurious CFG edges in match expressions 2024-09-24 13:09:33 +02:00
Tom Hvitved
3b753da74e Rust: Expose SuccessorType and sub classes 2024-09-24 13:09:00 +02:00
Owen Mansel-Chan
d7614a71f4 Merge pull request #17529 from github/workflow/coverage/update
Update CSV framework coverage reports
2024-09-24 11:37:12 +01:00
Tom Hvitved
6ae03e67e6 Rust: Add case for ParenExpr in CFG 2024-09-24 11:20:57 +02:00
github-actions[bot]
15bb670b3f Add changed framework coverage reports 2024-09-24 00:20:17 +00:00
Kevin Stubbings
01aa63e170 Add tests 2024-09-23 16:47:10 -07:00
Chris Smowton
7e8da94d9a Merge pull request #17216 from smowton/smowton/feature/golang-test-extraction
Go: support extracting test code
2024-09-23 16:43:42 +01:00
Chuan-kai Lin
1cd8af54f2 Merge pull request #17190 from github/cklin/diff-informed-java-queries
Java: add support for alert location restrictions
2024-09-23 08:39:24 -07:00
Chris Smowton
209f9ec93d Amend comments per review 2024-09-23 15:20:18 +01:00
yoff
e7bc71f2da Merge pull request #17540 from joefarebrother/python-const-compare
Python: Expand `StringConstCompareBarrier` sanitizer gaurds to cover additional constants
2024-09-23 16:14:09 +02:00
Joe Farebrother
48f9e0efe5 Adress review comments: Add missing deprecation + additional test case 2024-09-23 10:57:04 +01:00
Arthur Baars
04e3b39ffb Merge pull request #17537 from github/redsun82/rust-doctest-gen
Rust: take test code also from property descriptions
2024-09-23 11:41:32 +02:00
Arthur Baars
05173fa7ac Merge pull request #17539 from github/redsun82/rust-codegen-detach
Rust/Codegen: allow to "detach" property emission
2024-09-23 11:40:11 +02:00
Rasmus Wriedt Larsen
535db98823 Python: Minor simplification of ActiveThreatModelSource
Co-authored-by: Taus <tausbn@github.com>
2024-09-23 11:21:55 +02:00
Rasmus Wriedt Larsen
4a21a85e73 Merge branch 'main' into threat-models 2024-09-23 11:19:58 +02:00
Rasmus Wriedt Larsen
63c3a71d95 Merge branch 'main' into active-threat-model-source 2024-09-23 11:18:14 +02:00
Chris Smowton
e528a08794 Autoformat 2024-09-21 22:12:24 +01:00
Chris Smowton
bb44a2fc8c Populate pkgInfoMapping for test packages if relevant 2024-09-21 13:38:41 +01:00
Arthur Baars
7b4137fbc8 Rust: generate the extractor 2024-09-20 19:24:55 +02:00
Paolo Tranquilli
e48e18af20 Merge pull request #17527 from github/aibaars/rust-annotations
Rust: add QL doc annotations to schema
2024-09-20 18:08:37 +02:00
Arthur Baars
45d9d8a25a Address comments 2024-09-20 17:53:27 +02:00
Arthur Baars
1f21d75399 Merge pull request #17533 from github/redsun82/codegen-parametrized-pragmas
Codegen: introduce inherited pragmas and move remaining decorations
2024-09-20 17:53:05 +02:00
Chuan-kai Lin
75ec8ce58e Java: apply query alert restrictions 2024-09-20 07:47:58 -07:00
Joe Farebrother
7aa2816570 Add changenote 2024-09-20 15:19:54 +01:00
Anders Schack-Mulligen
3a1e50dcf9 Dataflow: Simplify diff-informed implementation and tweak flag name. 2024-09-20 07:07:10 -07:00
Paolo Tranquilli
c74b6be136 Rust/Codegen: allow to "detach" property emission
By using the `rust.detach` pragma on a property, we make that property
not appear in the generated struct as a field, and provide instead
a `generated::Class::emit_property` function that can be used to emit
the corresponding TRAP entry independently.
2024-09-20 16:06:22 +02:00
Joe Farebrother
81e99bf1bb Add tests 2024-09-20 15:05:51 +01:00
Arthur Baars
69a172c7ba Rust: accept trivial expected output 2024-09-20 15:51:06 +02:00
Arthur Baars
db06ad2ac3 Rust: codegen 2024-09-20 15:51:03 +02:00
Arthur Baars
2ee61f9aaa Rust: add placeholder QLdoc annotations 2024-09-20 15:51:02 +02:00
Arthur Baars
e6e0e6eb66 Rust: accept expected output 2024-09-20 15:51:01 +02:00
Arthur Baars
a9423f4bdb Rust: codegen 2024-09-20 15:50:59 +02:00
Arthur Baars
57458d8f38 Rust: remove qldoc annotations for classes that no longer exist 2024-09-20 15:50:58 +02:00
Arthur Baars
2fdc529ac9 Rust: add qldoc annotations to schema 2024-09-20 15:50:57 +02:00
Arthur Baars
b2bddd3415 Rust: write generated schema into schema/ast.py 2024-09-20 15:50:55 +02:00
Joe Farebrother
3001a570b2 Replace uses of StringConstCompare 2024-09-20 14:47:22 +01:00
Florin Coada
f4071ddb28 Merge pull request #17538 from github/coadaflorin/docs-typo-fix
Update index.html
2024-09-20 14:47:07 +01:00
Florin Coada
d290591187 Update index.html 2024-09-20 14:40:45 +01:00
Paolo Tranquilli
2a95068a0a Rust: take test code also from property descriptions 2024-09-20 15:12:13 +02:00
Geoffrey White
d7aa5f1022 Merge pull request #17497 from geoffw0/unusedvar
Rust: Placeholder queries for unused variable, unused value
2024-09-20 12:52:33 +01:00
Chris Smowton
bcb84a84e1 Only skip test packages at the file-extraction phase 2024-09-20 12:48:08 +01:00
Joe Farebrother
164cf27e67 Add additional constant checks to constant barrier gaurd 2024-09-20 12:46:10 +01:00
Paolo Tranquilli
4e59fa9035 Codegen: remove unneeded code 2024-09-20 12:47:45 +02:00
Paolo Tranquilli
f7afcd038a Codegen: move use_for_null to pragmas 2024-09-20 12:47:45 +02:00
Paolo Tranquilli
d2ebe00492 Codegen: move group to parametrized pragmas 2024-09-20 12:47:44 +02:00
Paolo Tranquilli
2533f18a6e Codegen: move ql.hideable to pragmas 2024-09-20 12:47:44 +02:00
Paolo Tranquilli
8d291ab938 Codegen: move qltest.test_with to parametrized pragmas 2024-09-20 12:47:44 +02:00
Paolo Tranquilli
3e2f886595 Codegen: allow inheritable pragmas 2024-09-20 12:47:43 +02:00
Paolo Tranquilli
1bffc2a7d7 Merge pull request #17532 from github/redsun82/codegen-parametrized-pragmas
Codegen: parametrized pragmas
2024-09-20 12:47:33 +02:00
Paolo Tranquilli
db00cb6827 Codegen: move class synth decorators to pragmas 2024-09-20 11:09:22 +02:00
Paolo Tranquilli
9d6ee09f65 Codegen: move rust.doc_test_signature to parametrized pragmas 2024-09-20 11:09:21 +02:00
Paolo Tranquilli
70997e8189 Codegen: move default_doc_name to parametrized pragma 2024-09-20 11:09:21 +02:00
Paolo Tranquilli
9f1d50ebd1 Codegen: allow parametrized pragmas 2024-09-20 11:09:21 +02:00
Chris Smowton
f5ff822681 Convert extract-tests option to an official extractor option 2024-09-20 10:03:54 +01:00
Chris Smowton
94cb99e51d Adjust test expectations 2024-09-20 10:03:53 +01:00
Chris Smowton
9d79feb4d3 Autoformat go 2024-09-20 10:03:52 +01:00
Chris Smowton
eb6918f88f Autoformat 2024-09-20 10:03:51 +01:00
Chris Smowton
fd592fa18f Add tests 2024-09-20 10:03:46 +01:00
Chris Smowton
c3dffc955b Apply review comments 2024-09-20 09:56:29 +01:00
Chris Smowton
76e6942594 Go: support extracting test code
This implements support for test extraction by two mechanisms:

* In autobuild mode, setting `CODEQL_EXTRACTOR_GO_EXTRACT_TESTS` to `true`.
* In manual build mode, tracing a `go test` command (`go test -c` is to be recommended for efficiency).

Go deals with test compilation by creating several extra packages on top of those expected from inspection of the source code (see docs of `packages.Load` for more detail): packages whose IDs include a suffix like `mydomain.com/mypackage [mydomain.com/mypackage.test]`, and packages containing generated test driver code like `mydomain.com/mypackage.test`. There are also additional packages like `mydomain.com/mypackage_tests` which are explicitly present in source code, but not compiled by a normal `go build`.

So far as I can tell, the purpose of the two variants of the package is to resolve dependency cycles (because the tests variant of the package can have more dependencies than the non-tests variant, and non-test code can compile against non-test package variants). Since the test package variants seems to be a superset of the non-tests variant, I employ the simple heuristic of ignoring the variant of each package with the shortest ID. I haven't seen a case where there are three or more variants of a package, so I expect this to always identify the tests variant as the preferred one. If several variants were extracted, and we were to attempt to match Golang's linkage strategy among the different variants, we would need to extend trap-file name and most top-level symbol trap IDs with the package variant they come from; I hope this won't prove necessary.

"Real" `_tests` packages, and wholly synthetic driver code packages, are extracted just like normal.
2024-09-20 09:56:28 +01:00
Arthur Baars
594045b634 Merge pull request #17530 from github/redsun82/codegen-annotate
Codegen: allow full annotation of classes
2024-09-20 10:38:44 +02:00
Tom Hvitved
f2e943f9ba Merge pull request #17520 from hvitved/cfg/no-kind-graph
Shared: Do not use `@kind graph` for CFG test output
2024-09-20 10:10:05 +02:00
Paolo Tranquilli
74c0fa7154 Codegen: allow annotations to add class decorations 2024-09-20 08:40:34 +02:00
Paolo Tranquilli
cc5882a3c3 Codegen: allow full annotation of classes 2024-09-20 06:55:17 +02:00
Arthur Baars
cf5d56addf Merge pull request #17524 from github/revert-17514-redsun82/codegen-include
Revert "Codegen: allow to include `.py` files in `schema.py`"
2024-09-19 21:43:28 +02:00
Jeroen Ketema
a065434dd7 Merge pull request #16811 from porcupineyhairs/curlssl
CPP: Disabled SSL certificate verification
2024-09-19 20:02:17 +02:00
Porcupiney Hairs
ee41e65e90 Include changes from review 2024-09-19 22:52:20 +05:30
Tom Hvitved
16813240ae Shared: Do not use @kind graph for CFG test output 2024-09-19 18:13:31 +02:00
Florin Coada
ec74595671 Merge pull request #17511 from github/changedocs/2.19.0
Adding unified changelog for 2.19.0
2024-09-19 17:05:30 +01:00
Simon Friis Vindum
95c18ce431 Merge pull request #17498 from paldepind/rust-improve-cfg
Rust: Improve CFG
2024-09-19 17:33:30 +02:00
Paolo Tranquilli
97cca76970 Revert "Codegen: allow to include .py files in schema.py" 2024-09-19 16:58:20 +02:00
Paolo Tranquilli
6a540d833e Merge pull request #17523 from github/redsun82/rust-break-up-schema
Codegen/Rust: allow breaking up schema file
2024-09-19 16:57:58 +02:00
Chris Smowton
fe1081e880 Merge pull request #17510 from mbaluda/patch-1
Model summary for `org.springframework.core.io.getInputStream` methods
2024-09-19 15:47:31 +01:00
Chris Smowton
0deefaddc5 Merge pull request #17483 from smowton/smowton/feature/csharp-dataflow-fewer-nodes-including-virtual-dispatch
C#: Restrict dataflow node creation to source and source-referenced entities [virtual-dispatch-inclusive variant]
2024-09-19 15:33:47 +01:00
Florin Coada
0e828bb5da Merge branch 'main' into changedocs/2.19.0 2024-09-19 15:16:49 +01:00
Chris Smowton
bb82dc1b18 Change note 2024-09-19 15:12:11 +01:00
Chris Smowton
bc9eb993b8 Remove unnecessary fromSource conditions 2024-09-19 15:08:08 +01:00
Paolo Tranquilli
a5e3fbf367 Codegen/Rust: allow breaking up schema file 2024-09-19 15:57:42 +02:00
Simon Friis Vindum
19697b9a77 Merge branch 'main' into rust-improve-cfg 2024-09-19 15:53:41 +02:00
Arthur Baars
f38f818578 Merge pull request #17516 from github/redsun82/codegen-annotate
Codegen: allow to attach docstrings after the definition
2024-09-19 15:35:16 +02:00
Owen Mansel-Chan
682f08ceb9 Merge pull request #17515 from owen-mc/go/run-ci-when-shared-libs-change
Go: Run CI when shared libraries change
2024-09-19 14:28:44 +01:00
Simon Friis Vindum
db9f5fdf81 Rust: Handle nested if expressions, address review comments 2024-09-19 15:10:37 +02:00
Arthur Baars
3c09f70e0d Merge pull request #17502 from github/aibaars/rust-extract-ast
Rust: ast-based extractor
2024-09-19 14:13:25 +02:00
Simon Friis Vindum
2511986324 Rust: Address PR review comments 2024-09-19 14:11:58 +02:00
Arthur Baars
919a9002bc Merge pull request #17514 from github/redsun82/codegen-include
Codegen: allow to include `.py` files in `schema.py`
2024-09-19 13:22:49 +02:00
Arthur Baars
3aa47a3950 Rust: accept test changes 2024-09-19 13:13:18 +02:00
Arthur Baars
1c0f60fa2e Rust: lines of code, exclude 'SourceFile' node 2024-09-19 13:00:52 +02:00
Arthur Baars
24f24855f0 Rust: update expected output 2024-09-19 13:00:51 +02:00
Arthur Baars
e19bca0de8 Rust: remove queries that no longer work 2024-09-19 13:00:50 +02:00
Arthur Baars
c3b10bf90b Rust: patch cfg implementation 2024-09-19 13:00:49 +02:00
Arthur Baars
80d32a2333 Rust: re-generate code 2024-09-19 13:00:46 +02:00
Arthur Baars
9104c3fc81 Rust: re-generate schema and extractor 2024-09-19 13:00:45 +02:00
Arthur Baars
1f30d5f41b Rust: generate schema.py and extractor from ungrammar 2024-09-19 13:00:05 +02:00
Paolo Tranquilli
c117a53fb0 Codegen: allow to attach docstrings after the definition 2024-09-19 12:43:34 +02:00
Owen Mansel-Chan
f2fbe64137 Go: Run CI when shared libraries change 2024-09-19 11:32:46 +01:00
Michael Nebel
f142af50b7 Shared: QL doc improvement. 2024-09-19 12:20:59 +02:00
Michael Nebel
de4a7da286 Java/C#: No longer sync CaptureModels.qll. 2024-09-19 12:20:55 +02:00
Michael Nebel
2033818e39 Java: Use the shared model generator implementation. 2024-09-19 12:20:51 +02:00
Michael Nebel
1f3b28a555 C#: Use the shared model generator implementation. 2024-09-19 12:20:46 +02:00
Michael Nebel
3b9f3c2c29 Shared: Add a model generator parameterised module. 2024-09-19 12:20:42 +02:00
Paolo Tranquilli
ec9bb1da56 Codegen: allow to include .py files in schema.py 2024-09-19 12:18:52 +02:00
Tom Hvitved
4baa4ae2aa Merge pull request #17513 from owen-mc/fix-test-expectations
C#/Go: Fix test expectations including double space
2024-09-19 12:17:18 +02:00
Michael B. Gale
a5ab5d9236 Merge pull request #17422 from github/dependabot/go_modules/go/extractor/extractor-dependencies-f3a1f89f55 2024-09-19 11:02:34 +01:00
Owen Mansel-Chan
ded52ccb8e Fix test expectations including double space 2024-09-19 11:01:38 +01:00
Florin Coada
54632b289e Adding unified changelog for 2.19.0 2024-09-19 10:03:07 +01:00
Arthur Baars
61ac8d66f5 Rust: make things compile 2024-09-19 10:51:52 +02:00
Arthur Baars
fabdb3c841 Rust: copy files from rust-analyzer's codegenerator
Files copied from: 50882fbfa2/xtask/src/codegen/grammar
2024-09-19 10:51:51 +02:00
Arthur Baars
5ccb45e7d3 Rust: add rust.ungram
Copied from 50882fbfa2/crates/syntax/rust.ungram
2024-09-19 10:51:46 +02:00
Arthur Baars
d5c0d41f98 Rust: add generate-schema project 2024-09-19 10:51:44 +02:00
Michael Nebel
4a9e3ee3aa Merge pull request #17363 from michaelnebel/modelgen/fieldbasedimprovements
C#/Java: Content based model generation improvements.
2024-09-19 10:49:11 +02:00
Tom Hvitved
cfa4cb432a Merge pull request #17504 from hvitved/dataflow/sink-provenance-space
Data flow: Remove spurious space in ` Sink:x` provenance
2024-09-19 10:21:38 +02:00
dependabot[bot]
67fa9738e6 Bump golang.org/x/tools
Bumps the extractor-dependencies group in /go/extractor with 1 update: [golang.org/x/tools](https://github.com/golang/tools).


Updates `golang.org/x/tools` from 0.24.0 to 0.25.0
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.24.0...v0.25.0)

---
updated-dependencies:
- dependency-name: golang.org/x/tools
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: extractor-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-19 03:46:50 +00:00
Paolo Tranquilli
9a8d9f857f Merge pull request #17491 from github/redsun82/rust-integration-test
Rust: add basic integration tests and fix archiving on Windows
2024-09-19 05:25:14 +02:00
Porcupiney Hairs
57d1035acd Include changes from review 2024-09-19 03:32:34 +05:30
Mauro Baluda
cab35a25a5 Remove duplicate summary for MultipartFile.getInputStream and update .expected file 2024-09-18 20:43:04 +02:00
Mauro Baluda
5ae51f0b56 Address review 2024-09-18 19:28:03 +02:00
Mauro Baluda
cfa14ad5eb Update org.springframework.core.io.model.yml
Model summary for `getInputStream` methods
2024-09-18 18:13:29 +02:00
Simon Friis Vindum
e43d39a0fe Merge pull request #17508 from paldepind/rust-consistency-queries-pack
Rust: Add consistency-queries pack
2024-09-18 14:17:52 +02:00
Tom Hvitved
485dc9619d Merge pull request #17506 from hvitved/rust/code-block-examples
Rust: Use ```rust for code block examples
2024-09-18 14:15:07 +02:00
Simon Friis Vindum
7c2b149728 Rust: Add consistency-queries pack 2024-09-18 14:09:41 +02:00
Geoffrey White
2769bd6f35 Rust: Make the placeholder queries produce no results, to avoid confusion. 2024-09-18 13:07:31 +01:00
Geoffrey White
3632a76eaf Rust: Add test annotations. 2024-09-18 13:05:06 +01:00
Geoffrey White
d79aa073ea Rust: Clean up the UnusedValue examples. 2024-09-18 13:03:09 +01:00
Geoffrey White
463a1254d3 Update rust/ql/src/queries/unusedentities/UnusedValueBad.rs
Co-authored-by: Paolo Tranquilli <redsun82@github.com>
2024-09-18 12:55:11 +01:00
Tom Hvitved
ed9008a064 Update expected test output 2024-09-18 13:51:02 +02:00
Simon Friis Vindum
bbf5902b18 Rust: Tweak imports 2024-09-18 13:48:50 +02:00
Tom Hvitved
43c0bd36be Rust: Run code generator 2024-09-18 13:48:02 +02:00
Tom Hvitved
5554c0f28f Rust: Use ```rust for code block examples
Also added some missing code block terminators.
2024-09-18 13:47:45 +02:00
Tom Hvitved
98b5ef5e01 Rust: Halt codegen on code block without ``` terminator 2024-09-18 13:47:44 +02:00
Simon Friis Vindum
6f555f3ad7 Merge branch 'main' into rust-improve-cfg 2024-09-18 13:42:51 +02:00
Tom Hvitved
2972a4eace Data flow: Remove spurious space in Sink:x provenance 2024-09-18 13:10:24 +02:00
Michael Nebel
24a101297c Merge pull request #15884 from michaelnebel/csharp/cleanupcil
C#: CIL and Dotnet cleanup (removal).
2024-09-18 11:43:41 +02:00
Chris Smowton
cfd281b319 Merge pull request #17400 from smowton/smowton/admin/further-golang-aliasing-tests
Go: add tests for dataflow relating to type aliasing
2024-09-18 10:30:37 +01:00
Tom Hvitved
0516d75c44 Merge pull request #17500 from hvitved/rust/move-generated
Rust: Use `elements/internal/generated` instead of `internal/generated`
2024-09-18 11:04:44 +02:00
Simon Friis Vindum
db351bdb05 Rust: Align test output with CI 2024-09-18 10:50:26 +02:00
Tom Hvitved
18ae8b14e9 Rust: Use elements/internal/generated instead of internal/generated 2024-09-18 10:44:20 +02:00
Paolo Tranquilli
c53179f742 Merge pull request #17499 from geoffw0/morestats
Rust: Add more summary stats.
2024-09-18 10:43:20 +02:00
Tom Hvitved
c5cbf82dbf Merge pull request #17495 from hvitved/codegen/internal
Codegen: Create `internal` folders
2024-09-18 10:42:04 +02:00
Simon Friis Vindum
dd25b3ecbe Rust: Don't use macro in test and add documentation string 2024-09-18 10:10:27 +02:00
Simon Friis Vindum
c18c35d737 Merge branch 'main' into rust-improve-cfg 2024-09-18 09:51:16 +02:00
Simon Friis Vindum
6a5a50521b Rust: Address QL suggestions for CFG implementation 2024-09-18 09:49:59 +02:00
Anders Schack-Mulligen
2837d2551a Merge pull request #17490 from aschackmull/java/capture-in-obinit
Java: Fix support for variable capture inside object initializers.
2024-09-18 09:29:01 +02:00
Michael Nebel
295861d577 Merge pull request #17459 from michaelnebel/csharp/accessormad
C#: Add MaD support for `Attribute.Getter` and `Attribute.Setter`.
2024-09-18 09:11:51 +02:00
Paolo Tranquilli
db812df06f Merge pull request #17492 from github/redsun82/rust-windows
Rust: add windows tools
2024-09-18 06:54:10 +02:00
Tom Hvitved
8c0d2e910c Swift: Run code generator 2024-09-17 20:25:57 +02:00
Tom Hvitved
9ea63fe716 Rust: Run code generator 2024-09-17 20:06:38 +02:00
Tom Hvitved
1433363523 Codegen: Create internal folders 2024-09-17 20:06:35 +02:00
Geoffrey White
83376afd15 Rust: Improve layout locality in summary stats. 2024-09-17 17:45:09 +01:00
Geoffrey White
07fccf8064 Rust: Add extracted + unextracted elements to summary stats. 2024-09-17 17:42:50 +01:00
Geoffrey White
6ebc615fd4 Rust: Add extracted files to summary stats. 2024-09-17 17:36:43 +01:00
Chris Smowton
0d0c94375d Adjust test expectations 2024-09-17 17:27:04 +01:00
Chris Smowton
2d5cbfd4c9 Elaborate comments 2024-09-17 17:18:48 +01:00
Chris Smowton
41726924e0 Update expectations 2024-09-17 17:02:47 +01:00
Chris Smowton
a803d3fb26 Add comments explaining tests 2024-09-17 17:02:46 +01:00
Chris Smowton
09015df8a4 Format 2024-09-17 17:02:45 +01:00
Chris Smowton
992b3c74fc Add data-flow tests for aliasing 2024-09-17 17:02:43 +01:00
Geoffrey White
a2bf2c7edb Rust: Fix query result columns. 2024-09-17 16:53:02 +01:00
Simon Friis Vindum
7a369f8734 Rust: Update CFG test and expected output 2024-09-17 17:34:11 +02:00
Simon Friis Vindum
73a430bd18 Merge branch 'main' into rust-improve-cfg 2024-09-17 17:31:10 +02:00
Geoffrey White
1c7d5217a0 Rust: Autoformat. 2024-09-17 16:24:28 +01:00
Geoffrey White
f93fd7cd6b Rust: Add qhelp and example for the unused variable query. 2024-09-17 16:13:25 +01:00
Geoffrey White
68f8e17186 Rust: Add a placeholder query + tests for unused variables query. 2024-09-17 16:13:23 +01:00
Geoffrey White
b7ad331b75 Rust: Add qhelp and example for the unused values query. 2024-09-17 16:13:22 +01:00
Geoffrey White
1fc6a0e103 Rust: Add placeholder query + tests for unused values query. 2024-09-17 16:13:21 +01:00
Simon Friis Vindum
6e868c2a6d Rust: CFG edges for break and continue with labels 2024-09-17 17:11:28 +02:00
Paolo Tranquilli
9f8c3c5778 Merge branch 'redsun82/rust-windows' into redsun82/rust-integration-test 2024-09-17 16:17:17 +02:00
Paolo Tranquilli
26d2e355bb Merge branch 'main' into redsun82/rust-windows 2024-09-17 16:16:48 +02:00
Michael Nebel
68165bbce4 C#/Java: Address review comments. 2024-09-17 16:09:17 +02:00
Chris Smowton
3e91f0f53f Expand range of callables requiring nodes to include unbound declarations of generic instantiations, static targets, and methods that have a body even if not flagged fromSource 2024-09-17 15:00:15 +01:00
Chris Smowton
349268cbf7 Expand the range of callables used in source to include potential virtual dispatch targets and referenced callables (e.g., in assigning a delegate) 2024-09-17 15:00:14 +01:00
Chris Smowton
66f48f767e Restrict dataflow node creation to source and source-referenced entities 2024-09-17 15:00:13 +01:00
Paolo Tranquilli
56f2732bbb Rust: ignore failing DB-CHECK 2024-09-17 15:35:52 +02:00
Paolo Tranquilli
5432493945 Rust: log detected manifests 2024-09-17 15:35:26 +02:00
Ian Lynagh
c7e3682597 Merge pull request #17451 from igfoo/igfoo/dbscheme
Java: Remove deprecated elements from dbscheme
2024-09-17 13:22:17 +01:00
Tom Hvitved
d680a549bd Merge pull request #16936 from hvitved/csharp/ssa-integration
C#: Adopt shared SSA data-flow integration
2024-09-17 13:45:31 +02:00
Simon Friis Vindum
581d0c59c4 Rust: Handle more AST nodes in the CFG 2024-09-17 13:05:27 +02:00
Felicity Chapman
0675ba0fa4 Merge pull request #17361 from github/12707-felicity-docs-landing
Update the Docs landing page for the CodeQL docs site
2024-09-17 11:40:53 +01:00
Ian Lynagh
9a398aa9a8 Java: Add up/downgrade scripts 2024-09-17 11:39:07 +01:00
Ian Lynagh
9f1c251809 Java: Follow removeal of typeVars.kind in qlls 2024-09-17 11:39:07 +01:00
Ian Lynagh
baace41488 Java: Remove stats for typeVars.kind 2024-09-17 11:39:06 +01:00
Ian Lynagh
b1f5f9a5cd Kotlin: Follow removal of typeVars.kind 2024-09-17 11:39:06 +01:00
Ian Lynagh
c5569cf5ad Java: Remove long-deprecated 'kind' from typeVars 2024-09-17 11:39:05 +01:00
Ian Lynagh
6968d7c17c Java: Remove duplicate/similar code from dbscheme
It's not been used for some time
2024-09-17 11:39:04 +01:00
Ian Lynagh
6166d061f2 Java: Move diagnostic_for next to diagnostics in the dbscheme
No code change, but it makes a bit more sense there
2024-09-17 11:39:04 +01:00
Ian Lynagh
7c99d9c648 Java: Remove snapshotDate from dbscheme
It's not been used for some time.
2024-09-17 11:39:03 +01:00
Ian Lynagh
9a62561336 Merge pull request #17484 from igfoo/igfoo/nestedName
Java: Deprecate RefType.nestedName(), and add RefType.getNestedName()
2024-09-17 11:37:16 +01:00
Paolo Tranquilli
89a8cbc536 Rust: use shared path utilities 2024-09-17 12:27:57 +02:00
Felicity Chapman
40fdd00e16 Merge pull request #17383 from github/10819-felicity-discovery
Update "About CodeQL" to cover the information needs of security researchers better
2024-09-17 11:10:52 +01:00
Felicity Chapman
7d49624e1c Update docs/codeql/codeql-overview/about-codeql.rst
Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com>
2024-09-17 11:09:48 +01:00
Anders Schack-Mulligen
a1a885efeb Java: Expand test. 2024-09-17 11:38:53 +02:00
Simon Friis Vindum
22edece201 Rust: Add CFG construction for if let expressions 2024-09-17 11:26:45 +02:00
Paolo Tranquilli
aae33db137 Rust: add basic integration tests
This adds testing of well-formed rust projects and workspaces, using
both `Cargo.toml` and `rust-project.json` manifests.
2024-09-17 11:23:39 +02:00
Paolo Tranquilli
afb9ffa50e Rust: add windows tools 2024-09-17 11:22:32 +02:00
Simon Friis Vindum
20e968751c Rust: Handle let statements with pattern and else branch in CFG 2024-09-17 10:54:48 +02:00
Anders Schack-Mulligen
20661a3c56 Java: Fix support for variable capture inside object initializers. 2024-09-17 10:42:21 +02:00
Michael Nebel
8d0cb07ba2 C#: Update the internal MaD attribute documentation. 2024-09-17 09:27:37 +02:00
Tom Hvitved
6618906380 Merge pull request #17488 from hvitved/rust/generated-internal
Rust: Move `codeql/rust/generated` files into `codeql/rust/internal/generated`
2024-09-17 09:12:44 +02:00
Paolo Tranquilli
fc9c4a8e14 Merge pull request #17477 from github/redsun82/rust-default-doc-signature
Rust/Codegen: make `() -> ()` the default signature
2024-09-17 08:51:46 +02:00
Tom Hvitved
efa52acf73 Rust: Move codeql/rust/generated files into codeql/rust/internal/generated 2024-09-17 08:51:24 +02:00
Paolo Tranquilli
0d8d9a3447 Merge branch 'main' into redsun82/rust-default-doc-signature 2024-09-17 08:29:01 +02:00
Tom Hvitved
9b8ba41c44 Merge pull request #17487 from hvitved/swift/change-note
Swift: Add change note
2024-09-16 19:57:24 +02:00
Tom Hvitved
961b077954 Swift: Add change note 2024-09-16 19:27:31 +02:00
Dave Bartolomeo
8b4114c422 Merge pull request #17485 from smowton/smowton/admin/merge-rc315-into-main
Merge rc/3.15 into main
2024-09-16 13:05:58 -04:00
Geoffrey White
27dca746ea Merge pull request #17465 from geoffw0/missing
Rust: Add Missing Elements query
2024-09-16 17:46:09 +01:00
Chris Smowton
01b47573b3 Merge remote-tracking branch 'origin/rc/3.15' into smowton/admin/merge-rc315-into-main 2024-09-16 17:36:18 +01:00
Paolo Tranquilli
f949ca919a Merge pull request #17479 from github/redsun82/rust-unextracted
Rust: introduce `Unextracted` and `Missing` "marker" classes
2024-09-16 18:26:55 +02:00
Ian Lynagh
41ed6e6695 Java: Deprecate RefType.nestedName(), and add RefType.getNestedName() 2024-09-16 17:16:25 +01:00
Geoffrey White
b907100d82 Rust: Rename files. 2024-09-16 16:25:56 +01:00
Geoffrey White
f60879bfb5 Rust: Rename missing -> unextracted. 2024-09-16 16:25:55 +01:00
Florin Coada
8090619117 Merge pull request #17456 from github/changedocs/2.18.4
CodeQL 2.18.4 unified changelog
2024-09-16 16:22:01 +01:00
Simon Friis Vindum
a935bded36 Rust: CFG for match expressions 2024-09-16 17:16:37 +02:00
Paolo Tranquilli
de4ab44e06 Merge branch 'main' into redsun82/rust-unextracted 2024-09-16 17:10:26 +02:00
Florin Coada
cbc390ebe5 Merge branch 'rc/3.15' into changedocs/2.18.4 2024-09-16 16:08:52 +01:00
Chris Smowton
30be6803c3 Merge pull request #17480 from github/post-release-prep/codeql-cli-2.19.0
Post-release preparation for codeql-cli-2.19.0
2024-09-16 16:06:58 +01:00
Paolo Tranquilli
d24d933ad7 Merge pull request #17460 from github/redsun82/rust-typed-labels
Rust: introduce typed labels
2024-09-16 16:56:37 +02:00
Paolo Tranquilli
37f3ea137b Merge pull request #17474 from github/redsun82/swift-cfg-order-disambuigation
Swift: tentative fix to Cfg disambuigation
2024-09-16 16:54:26 +02:00
Paolo Tranquilli
cf603108d4 Merge pull request #17478 from github/redsun82/python-fix-ql-test-exclusions
Python: replace `src_archive` exclusion patterns with `*.testproj` ones
2024-09-16 16:53:44 +02:00
Paolo Tranquilli
3eaee1249c Merge pull request #17464 from geoffw0/loc
Rust: Add lines-of-code queries
2024-09-16 16:47:12 +02:00
Paolo Tranquilli
1ce4707ff9 Merge branch 'main' into redsun82/rust-typed-labels 2024-09-16 16:44:55 +02:00
Paolo Tranquilli
d1704cfb14 Merge pull request #17444 from hvitved/rust/final-classes
Rust/Swift: Make all public AST classes `final`
2024-09-16 16:42:40 +02:00
Geoffrey White
3748365729 Rust: Comment out the printlin! macro invocations for now. 2024-09-16 15:29:13 +01:00
github-actions[bot]
79be301984 Post-release preparation for codeql-cli-2.19.0 2024-09-16 14:09:32 +00:00
Paolo Tranquilli
64f77051bd Rust: commit forgotten new files 2024-09-16 16:02:59 +02:00
Paolo Tranquilli
a4399a184a Rust: introduce Unextracted and Missing "marker" classes 2024-09-16 15:49:37 +02:00
Tom Hvitved
964e97c842 Update misc/codegen/lib/ql.py
Co-authored-by: Paolo Tranquilli <redsun82@github.com>
2024-09-16 15:48:13 +02:00
Michael Nebel
bdc00841c0 C#: Add change note. 2024-09-16 15:45:14 +02:00
Michael Nebel
0b579c0a1a C#: Update external models tests and expected test output. 2024-09-16 15:45:12 +02:00
Michael Nebel
308aca632e C#: Make support for Attribute.Getter and Attribute.Setter in MaD. 2024-09-16 15:45:09 +02:00
Michael Nebel
368ba1c5e2 C#: Update external models expected test output. 2024-09-16 15:45:07 +02:00
Michael Nebel
367bbc4039 C#: Add some examples of using attributes on properties and indexers for use in external models. 2024-09-16 15:45:05 +02:00
Michael Nebel
3c97bcb790 C#: Exclude properties from the Attribute selection. 2024-09-16 15:45:03 +02:00
Michael Nebel
5de9e7c3ad C#: Add change note. 2024-09-16 15:39:44 +02:00
Michael Nebel
add033249f Merge pull request #17475 from michaelnebel/csharp/indexerattributes
C#: Extract attributes on indexers.
2024-09-16 15:26:53 +02:00
Geoffrey White
63a635c89c Revert "Rust: Restrict the query to user code."
This reverts commit aed44ba5f3.
2024-09-16 13:46:43 +01:00
Paolo Tranquilli
10e42237f3 Codegen: fix test 2024-09-16 14:46:42 +02:00
Tom Hvitved
d0eae97bcf Address review comment 2024-09-16 14:46:23 +02:00
Geoffrey White
7a21b3ba46 Rust: Accept the new results. 2024-09-16 13:42:18 +01:00
Geoffrey White
4656b3a43d Revert "Rust: Only test the 'user code' queries, as the non-user stuff is not stable between platforms."
This reverts commit 00b9647aa1.
2024-09-16 13:39:50 +01:00
Paolo Tranquilli
e280e1ebee Merge pull request #17441 from github/redsun82/rust-cli-flags
Rust: make the cli flags override automatic
2024-09-16 14:37:43 +02:00
Paolo Tranquilli
8953ad6b76 Python: replace src_archive exclusion patterns with *.testproj ones
The `**/src_archive/**` exclusion patterns seem to have to do with
trying to exclude archived source files from being picked up for the
extractor while running the test itself. However it seems that directory
is not being used any more by `codeql` (which uses a `src` directory
instead).

A `*.testproj` exclusion pattern will work in a more robust way, by
excluding any file inside the database being built.
2024-09-16 14:30:55 +02:00
Tom Hvitved
8d68bdf4d6 Codegen: Fix return type of getResolveStep and resolve 2024-09-16 14:19:29 +02:00
Michael Nebel
03ee7b99d2 C#: Add downgrade script. 2024-09-16 14:12:12 +02:00
Michael Nebel
b76613901c C#: Add upgrade script. 2024-09-16 14:12:10 +02:00
Michael Nebel
0104f96f4a C#: Remove metadata_handle part of the extractor implementation. 2024-09-16 14:12:07 +02:00
Michael Nebel
a6f95c577a C#: Remove deprecated predicates. 2024-09-16 14:12:05 +02:00
Michael Nebel
982208cd81 C#: Remove all CIL and Dotnet related tables and types from the dbscheme. 2024-09-16 14:12:03 +02:00
Michael Nebel
21b3daa2c0 C#: Delete Dotnet and CIL library code. 2024-09-16 14:12:01 +02:00
Tom Hvitved
2cafa3c228 Merge pull request #6 from redsun82/rust/final-classes
Pre-commit: bump up `autopep8` check version and fix formatting
2024-09-16 14:09:58 +02:00
Paolo Tranquilli
95b32fb541 Pre-commit: bump up autopep8 check version and fix formatting 2024-09-16 14:03:48 +02:00
Geoffrey White
aed44ba5f3 Rust: Restrict the query to user code. 2024-09-16 12:56:06 +01:00
Tom Hvitved
575023f212 Swift: Add up/downgrade scripts 2024-09-16 13:40:06 +02:00
Tom Hvitved
d2f633b3b4 Swift: Manual changes after running code generator 2024-09-16 13:40:05 +02:00
Tom Hvitved
c785cd9d7b Swift: Revert Impl rename for manually added files 2024-09-16 13:40:03 +02:00
Tom Hvitved
4ab5a1a060 Swift: Run code generator 2024-09-16 13:40:02 +02:00
Tom Hvitved
5fc762d811 Swift: Add Impl suffix to all stub/implementation classes
```
find . -maxdepth 5 -type f -not -name "*Constructor.qll" -print | sed 's/.qll//g' | xargs -I '{}' mv '{}'.qll '{}'Impl.qll
```
2024-09-16 13:39:59 +02:00
Tom Hvitved
683ecc39d8 Rust: Adjust some generated Impl files 2024-09-16 13:39:57 +02:00
Tom Hvitved
4dd3059f16 Rust: Run code generator 2024-09-16 13:39:55 +02:00
Tom Hvitved
9c0cafeeb8 Codegen: Make public AST classes final 2024-09-16 13:39:53 +02:00
Paolo Tranquilli
73e9b46853 Rust/Codegen: make () -> () the default signature 2024-09-16 13:32:55 +02:00
Simon Friis Vindum
04aa7b471b Rust: Add support in CFG for various simple AST nodes 2024-09-16 13:22:15 +02:00
Tamás Vajk
d72f8b2e46 Merge pull request #17455 from tamasvajk/add-launch-json
C#: Add VSCode `launch.json`
2024-09-16 13:19:04 +02:00
Geoffrey White
fb6fbf6d21 Rust: Repair after Unimplemented.getLocation was removed. 2024-09-16 12:06:51 +01:00
Geoffrey White
00b9647aa1 Rust: Only test the 'user code' queries, as the non-user stuff is not stable between platforms. 2024-09-16 11:49:27 +01:00
Geoffrey White
c61970d8fe Merge branch 'main' into loc 2024-09-16 11:49:01 +01:00
Michael Nebel
f2360542e0 C#: Add change note. 2024-09-16 11:00:37 +02:00
Michael Nebel
7db73c8771 C#: Update expected test output. 2024-09-16 10:57:25 +02:00
Michael Nebel
1eff6fdf73 C#: Add extractor support for attributes on indexers. 2024-09-16 10:53:45 +02:00
Michael Nebel
5c5da3791e C#: Update attributes expected test output. 2024-09-16 10:53:00 +02:00
Paolo Tranquilli
ece815750e Merge branch 'main' into redsun82/rust-typed-labels 2024-09-16 10:51:07 +02:00
Michael Nebel
cc0d99a141 C#: Add attibute test examples for properties and indexers. 2024-09-16 10:50:51 +02:00
Simon Friis Vindum
c62c397cda Merge branch 'main' into rust-improve-cfg 2024-09-16 10:34:15 +02:00
Paolo Tranquilli
f1233b14e8 Rust: fix generated hierarchy 2024-09-16 10:06:01 +02:00
Arthur Baars
ab4788a2ce Merge branch 'main' into missing 2024-09-16 09:50:56 +02:00
Arthur Baars
762bf87663 Merge branch 'main' into loc 2024-09-16 09:50:48 +02:00
Paolo Tranquilli
cb53911224 Merge branch 'main' into redsun82/rust-cli-flags 2024-09-16 09:36:06 +02:00
Paolo Tranquilli
d74dd2161a Swift: tentative fix to Cfg disambuigation 2024-09-16 09:14:09 +02:00
Porcupiney Hairs
e768e2e5fe Include changes from review 2024-09-16 05:17:11 +05:30
Geoffrey White
36f54cc6c9 Rust: Clean up the query output. 2024-09-13 19:18:03 +01:00
Geoffrey White
551c4e83f4 Rust: Improve getNumberOfLinesOfCode (in particular, it will now include the closing of blocks { } ). 2024-09-13 18:23:11 +01:00
Geoffrey White
0d5c25b400 Rust: Repair getNumberOfLinesOfCode. 2024-09-13 18:19:01 +01:00
Geoffrey White
d21cbe57aa Merge branch 'main' into loc 2024-09-13 17:55:09 +01:00
Geoffrey White
57eafb81c7 Rust: Update results for changes on main. 2024-09-13 17:40:44 +01:00
Geoffrey White
81aeb3b755 Merge branch 'main' into missing 2024-09-13 17:33:46 +01:00
Paolo Tranquilli
8f93f5e34b Rust: move to Label<T> and mark unsafety of from_untyped 2024-09-13 17:17:19 +02:00
Simon Friis Vindum
afa4e79756 Rust: Add support for more AST nodes to CFG contruction 2024-09-13 16:22:18 +02:00
Simon Friis Vindum
9061536cca Rust: Make logical operator pre order nodes and eliminate impossible paths in CFG 2024-09-13 16:14:33 +02:00
Geoffrey White
a3de3a1c51 Rust: Update results for latest main. 2024-09-13 15:10:38 +01:00
Geoffrey White
af7cd238e5 Rust: Test query for missing elements. 2024-09-13 15:09:18 +01:00
Geoffrey White
2894653421 Rust: Query for missing elements. 2024-09-13 15:09:17 +01:00
Rasmus Wriedt Larsen
13a4df9b68 Go: autoformat 2024-09-13 16:07:27 +02:00
Geoffrey White
6e01270fec Rust: Better (still incomplete) results on latest main. 2024-09-13 15:06:22 +01:00
Geoffrey White
fdf079265d Rust: Add test. 2024-09-13 15:05:20 +01:00
Geoffrey White
c124820256 Rust: Add summary stats query showing all of the summary data, for convenience. 2024-09-13 15:05:19 +01:00
Geoffrey White
6e9f2a3b61 Rust: Add tests. 2024-09-13 15:05:18 +01:00
Geoffrey White
2f98c5ba47 Rust: Add lines-of-code queries. 2024-09-13 15:05:17 +01:00
Paolo Tranquilli
faf1eeeb0d Rust: introduce typed labels 2024-09-13 13:57:14 +02:00
Paolo Tranquilli
23dd572d5e Rust: add CODEQL_ base env layer 2024-09-13 13:39:39 +02:00
Simon Friis Vindum
61aad2ec68 Rust: Sort CFG trees and add scope for closures 2024-09-13 11:57:31 +02:00
Simon Friis Vindum
1a85dfd9ce Rust: Loops propagate CFG return completions but captures continue and break 2024-09-13 11:51:16 +02:00
Simon Friis Vindum
b979df61ea Rust: Handle functions correctly through scope in CFG 2024-09-13 11:40:26 +02:00
Florin Coada
194c2fa9c4 Add changedocs for 2.18.4 2024-09-13 10:18:04 +01:00
Tamas Vajk
549b294a05 C#: Add VSCode launch.json 2024-09-13 09:42:55 +02:00
Kevin Stubbings
c30332818f Reorder and rename 2024-09-13 00:41:55 -07:00
Kevin Stubbings
03f375e436 missed some 2024-09-13 00:21:33 -07:00
Paolo Tranquilli
403cc3df90 Rust: avoid cli flag defaults overriding env settings 2024-09-13 06:50:12 +02:00
Kevin Stubbings
7657b3e115 Fix tests 2024-09-12 21:30:32 -07:00
Kevin Stubbings
831d522025 First round feedback 2024-09-12 20:49:10 -07:00
Simon Friis Vindum
f73680ba21 Rust: Handle short-circuiting logical binary operators 2024-09-12 17:30:05 +02:00
Simon Friis Vindum
c821ec21bb Rust: CFG edge for return in functions 2024-09-12 16:25:43 +02:00
Simon Friis Vindum
e1f2fa8c7e Rust: Support break and continue in loops 2024-09-12 14:07:43 +02:00
Simon Friis Vindum
3dc517c82b Rust: Handle absence of else branch in if expression in CFG 2024-09-12 10:35:00 +02:00
Rasmus Wriedt Larsen
66b61ee25a Go/Java/C#: Add change-note 2024-09-12 10:16:55 +02:00
Rasmus Wriedt Larsen
8c10155eb7 mass rename to ActiveThreatModelSource 2024-09-12 10:16:55 +02:00
Simon Friis Vindum
67a06cb772 Rust: Support loop in CFG 2024-09-12 09:29:19 +02:00
Paolo Tranquilli
5ae8824303 Rust: add context to parameter file expansion errors 2024-09-12 08:56:07 +02:00
Paolo Tranquilli
6adf88542e Rust: fix linting script 2024-09-12 08:53:08 +02:00
Paolo Tranquilli
0a8c0f5ab4 Rust: fix bazel build 2024-09-12 08:46:50 +02:00
Chuan-kai Lin
ff78bebf19 Shared support for alert filtering 2024-09-11 13:18:26 -07:00
Paolo Tranquilli
5bfe2a9e18 Merge branch 'main' into redsun82/rust-cli-flags 2024-09-11 18:00:47 +02:00
Paolo Tranquilli
1b3a5cdab1 Rust: make the cli flags override automatic
This makes the clap flags overlay over `Config` entirely derived via an
attribute macro. Also, the `--intputs-file` option is replaced by a more
standard and versatile `@` parameter file mechanism.
2024-09-11 17:28:59 +02:00
Rasmus Wriedt Larsen
e11bfc27bd Docs: Fix link 2024-09-10 16:53:52 +02:00
Rasmus Wriedt Larsen
e35c2b243a Docs: Include 'Threat models' for Python 2024-09-10 16:44:03 +02:00
Michael Nebel
0abc08c773 C#: Add some synthetic field content based examples. 2024-09-10 15:24:00 +02:00
Michael Nebel
b94940b6d9 C#: Adjust existing model generator tests and update expected output. 2024-09-10 15:23:57 +02:00
Michael Nebel
da012a7a44 C#: Add the capture content summary models query. 2024-09-10 15:23:54 +02:00
Michael Nebel
e94890280a C#: Sync changes and make language specific parts. 2024-09-10 15:23:51 +02:00
Michael Nebel
0fbeca14ad Java: Add content based example with multiple paths. 2024-09-10 15:23:44 +02:00
Michael Nebel
9149a17d79 Java: Only keep the best generated model in terms of taint/value. 2024-09-10 15:23:38 +02:00
Michael Nebel
d7e61d07d1 Java: Update some model generator test cases. 2024-09-10 15:23:34 +02:00
Michael Nebel
d2c98c86dc Java: Improve content based model generation. 2024-09-10 15:23:20 +02:00
Michael Nebel
7c0101ad06 Shared: Add some helper predicates to the AccessPath class in content flow. 2024-09-10 15:23:08 +02:00
Rasmus Wriedt Larsen
038bc832a7 Go/Java/C#: Rename to ActiveThreatModelSource
As part of adding support for threat-models to Python/JS (see
https://github.com/github/codeql/pull/17203), we ran into some trouble
with name clashes.

Naming in existing languages supporting threat-models:
- `SourceNode` (for QL only modeling)
- `ThreatModelFlowSource` (for active sources from QL or data-extensions)

However, since we use `LocalSourceNode` in Python, and `SourceNode` in
JS (for local source nodes), it seems a bit confusing to follow the same
naming convention as other languages, and we had to come up with new names.

Initially I used `ThreatModelSource` for the "QL only modeling", but
that meant that we needed a new name to represent the active sources
coming from either QL or data-extensions... for this I came up with
`ActiveThreatModelSource`, and I really liked it. To me, it's much
clearer that this class only contains the currently active threat
model sources.

So to align languages, I got approval from @michaelnebel to rename the
existing classes.
2024-09-10 14:46:15 +02:00
Rasmus Wriedt Larsen
5ff7b6557f Python: Add links to threat-model docs 2024-09-10 14:32:39 +02:00
Rasmus Wriedt Larsen
cbebf7b392 Python: Additional threatModelSource annotations 2024-09-10 14:32:39 +02:00
Rasmus Wriedt Larsen
333367c07d Python: Add threat-modeling of raw_input 2024-09-10 14:32:39 +02:00
Rasmus Wriedt Larsen
7d3793e718 Docs: Update threat-model list to include Python 2024-09-10 14:32:38 +02:00
Rasmus Wriedt Larsen
0ccb5b198a Python: Add change-note 2024-09-10 14:32:38 +02:00
Rasmus Wriedt Larsen
a0b24d6194 Python: Add e2e threat-model test 2024-09-10 14:32:38 +02:00
Rasmus Wriedt Larsen
8d8cd05b94 Python: Add basic support for database threat-model 2024-09-10 14:32:37 +02:00
Rasmus Wriedt Larsen
7483075b7e Python: Fixup modeling of os.open 2024-09-10 14:32:37 +02:00
Rasmus Wriedt Larsen
d245db54a1 Python: Model file threat-model 2024-09-10 14:32:37 +02:00
Rasmus Wriedt Larsen
66f389a4b6 Python: Model stdin thread-model 2024-09-10 14:32:36 +02:00
Rasmus Wriedt Larsen
e1801f3a29 Python: Proper threat-model handling for argparse 2024-09-10 14:32:36 +02:00
Rasmus Wriedt Larsen
56c85ffe54 Python: Fixup threat-models for os.environ.get()
Since using `.DictionaryElementAny` doesn't actually do a store on the
source, (so we can later follow any dict read-steps).

I added the ensure_tainted steps to highlight that the result of the
WHOLE expression ends up "tainted", and that we don't just mark
`os.environ` as the source without further flow.
2024-09-10 14:32:36 +02:00
Rasmus Wriedt Larsen
b9239d7101 Python: Add basic support for environment/commandargs threat-models 2024-09-10 14:32:36 +02:00
Rasmus Wriedt Larsen
528f08fb83 Python: Make queries use ActiveThreatModelSource 2024-09-10 14:32:35 +02:00
Felicity Chapman
967367bba6 Apply suggestions from code review
Co-authored-by: Joe Clark <31087804+jc-clark@users.noreply.github.com>
2024-09-06 12:30:18 +01:00
Felicity Chapman
529bee4d73 Add link to MRVA 2024-09-04 15:57:01 +01:00
Felicity Chapman
4cdef853d2 Add metadata to two key topics to help with SEO 2024-09-04 15:42:18 +01:00
Felicity Chapman
e58bb88ee8 Make more security researcher focused 2024-09-04 15:29:47 +01:00
Felicity Chapman
68cbe35d96 Fix a bad link 2024-09-03 13:08:07 +01:00
Felicity Chapman
44ca530087 Update template to match changes to landing page 2024-09-03 12:59:29 +01:00
Felicity Chapman
f44905324e Add article on running queries 2024-09-03 12:55:56 +01:00
Felicity Chapman
5f1e62aefe Update landing page to focus on language 2024-09-03 12:54:45 +01:00
Kevin Stubbings
c60f459530 Grammar 2024-08-26 23:57:19 -07:00
Kevin Stubbings
812abea0de change-notes 2024-08-26 22:25:00 -07:00
Kevin Stubbings
0420d25c13 refactor 2024-08-26 22:09:24 -07:00
Kevin Stubbings
1db7865d49 Corrections 2024-08-26 22:06:12 -07:00
Kevin Stubbings
8bf8893307 Add support for vulnerable CORS middlewares 2024-08-26 21:30:48 -07:00
Rasmus Wriedt Larsen
8f7dec07b8 Python: Remove 'response' from default threat-models
I didn't want to put the configuration file in
`semmle/python/frameworks/**/*.model.yml`, so created `ext/` as in other
languages
2024-08-19 10:54:48 +02:00
Rasmus Wriedt Larsen
617ab27c75 Python: Add test showing default active threat-models 2024-08-19 10:54:48 +02:00
Rasmus Wriedt Larsen
766dcc4dd6 ThreatModels: Expose knownThreatModel
Without, it's impossible to write test showing what threat-models are
active by default... unless I provide a hardcoded list in the test
itself, which is not any fun.
2024-08-19 10:54:47 +02:00
Rasmus Wriedt Larsen
5ec8e5dd30 Python: Setup support for threat-models
Naming in other languages:
- `SourceNode` (for QL only modeling)
- `ThreatModelFlowSource` (for active sources from QL or data-extensions)

However, since we use `LocalSourceNode` in Python, and `SourceNode` in
JS (for local source nodes), it seems a bit confusing to follow the same
naming convention as other languages, and instead I came up with new names.
2024-08-19 10:54:47 +02:00
Tom Hvitved
89a2381165 C#: Adopt shared SSA data-flow integration 2024-08-14 08:39:17 +02:00
Porcupiney Hairs
a7cdf0e2fd CPP: Disabled SSL certificate verification
Disable SSL certificate verification can expose the communication to MITM attacks.

This PR adds a query to detect the same. This also include the tests and qhelp for the same.
2024-06-23 14:27:04 +05:30
4508 changed files with 121281 additions and 63484 deletions

View File

@@ -3,6 +3,7 @@ on:
push:
paths:
- "go/**"
- "shared/**"
- .github/workflows/go-tests.yml
- .github/actions/**
- codeql-workspace.yml
@@ -12,6 +13,7 @@ on:
pull_request:
paths:
- "go/**"
- "shared/**"
- .github/workflows/go-tests.yml
- .github/actions/**
- codeql-workspace.yml

View File

@@ -15,7 +15,7 @@ repos:
- id: clang-format
- repo: https://github.com/pre-commit/mirrors-autopep8
rev: v1.6.0
rev: v2.0.4
hooks:
- id: autopep8
files: ^misc/codegen/.*\.py

98
Cargo.lock generated
View File

@@ -96,6 +96,16 @@ version = "1.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8"
[[package]]
name = "argfile"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a1cc0ba69de57db40674c66f7cf2caee3981ddef084388482c95c0e2133e5e8"
dependencies = [
"fs-err",
"os_str_bytes",
]
[[package]]
name = "arrayvec"
version = "0.7.6"
@@ -255,7 +265,7 @@ dependencies = [
"chalk-ir",
"ena",
"indexmap 2.5.0",
"itertools",
"itertools 0.12.1",
"petgraph",
"rustc-hash",
"tracing",
@@ -360,9 +370,11 @@ name = "codeql-rust"
version = "0.1.0"
dependencies = [
"anyhow",
"argfile",
"clap",
"codeql-extractor",
"figment",
"itertools 0.13.0",
"log",
"num-traits",
"ra_ap_base_db",
@@ -370,10 +382,12 @@ dependencies = [
"ra_ap_hir_def",
"ra_ap_ide_db",
"ra_ap_load-cargo",
"ra_ap_parser",
"ra_ap_paths",
"ra_ap_project_model",
"ra_ap_syntax",
"ra_ap_vfs",
"rust-extractor-macros",
"serde",
"serde_with",
"stderrlog",
@@ -643,6 +657,15 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "fs-err"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41"
dependencies = [
"autocfg",
]
[[package]]
name = "fsevent-sys"
version = "4.1.0"
@@ -658,6 +681,16 @@ version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a"
[[package]]
name = "generate-schema"
version = "0.1.0"
dependencies = [
"itertools 0.10.5",
"proc-macro2",
"quote",
"ungrammar",
]
[[package]]
name = "getrandom"
version = "0.2.15"
@@ -827,6 +860,15 @@ version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.12.1"
@@ -836,6 +878,15 @@ dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.11"
@@ -1064,6 +1115,15 @@ version = "11.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9"
[[package]]
name = "os_str_bytes"
version = "7.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ac44c994af577c799b1b4bd80dc214701e349873ad894d6cdf96f4f7526e0b9"
dependencies = [
"memchr",
]
[[package]]
name = "overload"
version = "0.1.1"
@@ -1303,7 +1363,7 @@ checksum = "c7c38520eb4770af561c34b908431f4e548c3282093cf3daf3c6e566d99a2937"
dependencies = [
"arrayvec",
"either",
"itertools",
"itertools 0.12.1",
"ra_ap_base_db",
"ra_ap_cfg",
"ra_ap_hir_def",
@@ -1335,7 +1395,7 @@ dependencies = [
"fst",
"hashbrown 0.14.5",
"indexmap 2.5.0",
"itertools",
"itertools 0.12.1",
"la-arena",
"ra-ap-rustc_abi",
"ra-ap-rustc_parse_format",
@@ -1365,7 +1425,7 @@ dependencies = [
"cov-mark",
"either",
"hashbrown 0.14.5",
"itertools",
"itertools 0.12.1",
"la-arena",
"ra_ap_base_db",
"ra_ap_cfg",
@@ -1400,7 +1460,7 @@ dependencies = [
"either",
"ena",
"indexmap 2.5.0",
"itertools",
"itertools 0.12.1",
"la-arena",
"nohash-hasher",
"oorandom",
@@ -1437,7 +1497,7 @@ dependencies = [
"either",
"fst",
"indexmap 2.5.0",
"itertools",
"itertools 0.12.1",
"line-index",
"memchr",
"nohash-hasher",
@@ -1483,7 +1543,7 @@ checksum = "82e6f24b61f1ef1f3a756493d1fb7e711b69b2e4d5f4746fcb959313dfd41471"
dependencies = [
"anyhow",
"crossbeam-channel",
"itertools",
"itertools 0.12.1",
"ra_ap_hir_expand",
"ra_ap_ide_db",
"ra_ap_intern",
@@ -1578,7 +1638,7 @@ checksum = "db83d1844c74b22c110c4b8e8f2519be2b1723964008527281a11c3398749756"
dependencies = [
"anyhow",
"cargo_metadata",
"itertools",
"itertools 0.12.1",
"la-arena",
"ra_ap_base_db",
"ra_ap_cfg",
@@ -1602,7 +1662,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "370b302873eeafd07ccc6a714fc9395cae11e385955ccb78081093ee3b86f94e"
dependencies = [
"indexmap 2.5.0",
"itertools",
"itertools 0.12.1",
"lock_api",
"oorandom",
"parking_lot",
@@ -1649,7 +1709,7 @@ checksum = "bb63ff9d6b11b4553fc0835f16705975258905e3b1230fcf1ddbf24c46aff69d"
dependencies = [
"always-assert",
"crossbeam-channel",
"itertools",
"itertools 0.12.1",
"jod-thread",
"libc",
"miow",
@@ -1665,7 +1725,7 @@ dependencies = [
"cov-mark",
"either",
"indexmap 2.5.0",
"itertools",
"itertools 0.12.1",
"ra-ap-rustc_lexer",
"ra_ap_parser",
"ra_ap_stdx",
@@ -1699,7 +1759,7 @@ version = "0.0.232"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cb72ee1901baec556f4f2ef77e287d749ac0e973f063990672d6207b076aeac"
dependencies = [
"itertools",
"itertools 0.12.1",
"text-size",
]
@@ -1875,6 +1935,14 @@ dependencies = [
"text-size",
]
[[package]]
name = "rust-extractor-macros"
version = "0.1.0"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "rustc-hash"
version = "1.1.0"
@@ -2287,6 +2355,12 @@ dependencies = [
"version_check",
]
[[package]]
name = "ungrammar"
version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e5df347f0bf3ec1d670aad6ca5c6a1859cd9ea61d2113125794654ccced68f"
[[package]]
name = "unicode-ident"
version = "1.0.13"

View File

@@ -6,6 +6,8 @@ members = [
"shared/tree-sitter-extractor",
"ruby/extractor",
"rust/extractor",
"rust/extractor/macros",
"rust/generate-schema",
]
[patch.crates-io]

View File

@@ -60,6 +60,8 @@ r.from_cargo(
"//:Cargo.toml",
"//ruby/extractor:Cargo.toml",
"//rust/extractor:Cargo.toml",
"//rust/extractor/macros:Cargo.toml",
"//rust/generate-schema:Cargo.toml",
"//shared/tree-sitter-extractor:Cargo.toml",
],
)
@@ -126,6 +128,7 @@ use_repo(
"kotlin-compiler-1.9.20-Beta",
"kotlin-compiler-2.0.0-RC1",
"kotlin-compiler-2.0.20-Beta2",
"kotlin-compiler-2.1.0-Beta1",
"kotlin-compiler-embeddable-1.5.0",
"kotlin-compiler-embeddable-1.5.10",
"kotlin-compiler-embeddable-1.5.20",
@@ -139,6 +142,7 @@ use_repo(
"kotlin-compiler-embeddable-1.9.20-Beta",
"kotlin-compiler-embeddable-2.0.0-RC1",
"kotlin-compiler-embeddable-2.0.20-Beta2",
"kotlin-compiler-embeddable-2.1.0-Beta1",
"kotlin-stdlib-1.5.0",
"kotlin-stdlib-1.5.10",
"kotlin-stdlib-1.5.20",
@@ -152,6 +156,7 @@ use_repo(
"kotlin-stdlib-1.9.20-Beta",
"kotlin-stdlib-2.0.0-RC1",
"kotlin-stdlib-2.0.20-Beta2",
"kotlin-stdlib-2.1.0-Beta1",
)
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")

View File

@@ -1,4 +1,5 @@
provide:
- "*/ql/base/qlpack.yml"
- "*/ql/src/qlpack.yml"
- "*/ql/lib/qlpack.yml"
- "*/ql/test*/qlpack.yml"

View File

@@ -57,10 +57,6 @@
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll"
],
"Model as Data Generation Java/C# - CaptureModels": [
"java/ql/src/utils/modelgenerator/internal/CaptureModels.qll",
"csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll"
],
"Sign Java/C#": [
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/Sign.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/Sign.qll"
@@ -355,5 +351,9 @@
"Python model summaries test extension": [
"python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml",
"python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml"
],
"Diagnostics.qll": [
"ruby/ql/lib/codeql/ruby/Diagnostics.qll",
"rust/ql/lib/codeql/rust/Diagnostics.qll"
]
}

View File

@@ -1,3 +1,7 @@
## 2.0.1
No user-facing changes.
## 2.0.0
### Breaking Changes

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 2.0.0
lastReleaseVersion: 2.0.1

View File

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

View File

@@ -500,6 +500,17 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* Gets the nearest enclosing AccessHolder.
*/
override AccessHolder getEnclosingAccessHolder() { result = this.getDeclaringType() }
/**
* Holds if this function has extraction errors that create an `ErrorExpr`.
*/
predicate hasErrors() {
exists(ErrorExpr e |
e.getEnclosingFunction() = this and
// Exclude the first allocator call argument because it is always extracted as `ErrorExpr`.
not exists(NewOrNewArrayExpr new | e = new.getAllocatorCall().getArgument(0))
)
}
}
pragma[noinline]
@@ -651,7 +662,8 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
/**
* Holds if this declaration is an implicit function declaration, that is,
* where a function is used before it is declared (under older C standards).
* where a function is used before it is declared (under older C standards,
* or when there were parse errors).
*/
predicate isImplicit() { fun_implicit(underlyingElement(this)) }

View File

@@ -39,8 +39,8 @@ class Type extends Locatable, @type {
/**
* Gets a specifier of this type, recursively looking through `typedef` and
* `decltype`. For example, in the context of `typedef const int *restrict
* t`, the type `volatile t` has specifiers `volatile` and `restrict` but not
* `decltype`. For example, in the context of `typedef const int *restrict t`,
* the type `volatile t` has specifiers `volatile` and `restrict` but not
* `const` since the `const` is attached to the type being pointed to rather
* than the pointer itself.
*/

View File

@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
predicate observeDiffInformedIncrementalMode() { none() }
}
deprecated private import Impl<Config> as I

View File

@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
predicate observeDiffInformedIncrementalMode() { none() }
}
deprecated private import Impl<Config> as I

View File

@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
predicate observeDiffInformedIncrementalMode() { none() }
}
deprecated private import Impl<Config> as I

View File

@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
predicate observeDiffInformedIncrementalMode() { none() }
}
deprecated private import Impl<Config> as I

View File

@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
predicate observeDiffInformedIncrementalMode() { none() }
}
deprecated private import Impl<Config> as I

View File

@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
predicate observeDiffInformedIncrementalMode() { none() }
}
deprecated private import Impl<Config> as I

View File

@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
predicate observeDiffInformedIncrementalMode() { none() }
}
deprecated private import Impl<Config> as I

View File

@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
predicate observeDiffInformedIncrementalMode() { none() }
}
deprecated private import Impl<Config> as I

View File

@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
predicate observeDiffInformedIncrementalMode() { none() }
}
deprecated private import Impl<Config> as I

View File

@@ -546,7 +546,7 @@ module ProductFlow {
Flow1::PathGraph::edges(pred1, succ1, _, _) and
exists(ReturnKindExt returnKind |
succ1.getNode() = returnKind.getAnOutNode(call) and
paramReturnNode(_, pred1.asParameterReturnNode(), _, returnKind)
returnKind = getParamReturnPosition(_, pred1.asParameterReturnNode()).getKind()
)
}
@@ -574,7 +574,7 @@ module ProductFlow {
Flow2::PathGraph::edges(pred2, succ2, _, _) and
exists(ReturnKindExt returnKind |
succ2.getNode() = returnKind.getAnOutNode(call) and
paramReturnNode(_, pred2.asParameterReturnNode(), _, returnKind)
returnKind = getParamReturnPosition(_, pred2.asParameterReturnNode()).getKind()
)
}

View File

@@ -118,19 +118,34 @@ abstract class FormattingFunction extends ArrayFunction, TaintFunction {
/**
* Gets the position of the first format argument, corresponding with
* the first format specifier in the format string.
* the first format specifier in the format string. We ignore all
* implicit function definitions.
*/
int getFirstFormatArgumentIndex() {
result = this.getNumberOfParameters() and
// the formatting function either has a definition in the snapshot, or all
// The formatting function either has a definition in the snapshot, or all
// `DeclarationEntry`s agree on the number of parameters (otherwise we don't
// really know the correct number)
(
this.hasDefinition()
or
forall(FunctionDeclarationEntry fde | fde = this.getADeclarationEntry() |
result = fde.getNumberOfParameters()
)
if this.hasDefinition()
then result = this.getDefinition().getNumberOfParameters()
else result = this.getNumberOfExplicitParameters()
}
/**
* Gets a non-implicit function declaration entry.
*/
private FunctionDeclarationEntry getAnExplicitDeclarationEntry() {
result = this.getADeclarationEntry() and
not result.isImplicit()
}
/**
* Gets the number of parameters, excluding any parameters that have been defined
* from implicit function declarations. If there is some inconsistency in the number
* of parameters, then don't return anything.
*/
private int getNumberOfExplicitParameters() {
forex(FunctionDeclarationEntry fde | fde = this.getAnExplicitDeclarationEntry() |
result = fde.getNumberOfParameters()
)
}

View File

@@ -160,6 +160,26 @@ private module InvalidPointerToDerefBarrier {
}
}
/**
* BEWARE: This configuration uses an unrestricted sink, so accessing its full
* flow computation or any stages beyond the first 2 will likely diverge.
* Stage 1 will still be fast and we use it to restrict the subsequent sink
* computation.
*/
private module InvalidPointerReachesConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { invalidPointerToDerefSource(_, _, source) }
predicate isSink(DataFlow::Node sink) { any() }
predicate isBarrier(DataFlow::Node node) { InvalidPointerToDerefConfig::isBarrier(node) }
int fieldFlowBranchLimit() { result = invalidPointerToDereferenceFieldFlowBranchLimit() }
}
private module InvalidPointerReachesFlow = DataFlow::Global<InvalidPointerReachesConfig>;
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplCommon as DataFlowImplCommon
/**
* A configuration to track flow from a pointer-arithmetic operation found
* by `AllocToInvalidPointerConfig` to a dereference of the pointer.
@@ -173,8 +193,13 @@ private module InvalidPointerToDerefConfig implements DataFlow::StateConfigSig {
invalidPointerToDerefSource(_, pai, source)
}
pragma[inline]
predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink(sink, _, _, _, _) }
predicate isSink(DataFlow::Node sink) {
exists(DataFlowImplCommon::NodeEx n |
InvalidPointerReachesFlow::Stages::Stage1::sinkNode(n, _) and
n.asNode() = sink and
isInvalidPointerDerefSink(sink, _, _, _, _)
)
}
predicate isSink(DataFlow::Node sink, FlowState pai) { none() }

View File

@@ -72,7 +72,6 @@ module FlowFromFree<FlowFromFreeParamSig P> {
predicate isSource(DataFlow::Node node, FlowState state) { isFree(node, _, state, _) }
pragma[inline]
predicate isSink(DataFlow::Node sink, FlowState state) {
exists(Expr e, DataFlow::Node source, DeallocationExpr dealloc |
P::isSink(sink, e) and

View File

@@ -57,5 +57,5 @@ where
not declarationHasSideEffects(v) and
not exists(AsmStmt s | f = s.getEnclosingFunction()) and
not v.getAnAttribute().getName() = "unused" and
not any(ErrorExpr e).getEnclosingFunction() = f // unextracted expr may use `v`
not f.hasErrors() // Unextracted expressions may use `v`
select v, "Variable " + v.getName() + " is not used."

View File

@@ -1,9 +1,15 @@
## 1.2.4
### Minor Analysis Improvements
* Fixed false positives in the `cpp/wrong-number-format-arguments` ("Too few arguments to formatting function") query when the formatting function has been declared implicitly.
## 1.2.3
### Minor Analysis Improvements
* Removed false positives caused by buffer accesses in unreachable code.
* Removed false positives caused by inconsistent type checking.
* Removed false positives caused by buffer accesses in unreachable code
* Removed false positives caused by inconsistent type checking
* Add modeling of C functions that don't throw, thereby increasing the precision of the `cpp/incorrect-allocation-error-handling` ("Incorrect allocation-error handling") query. The query now produces additional true positives.
## 1.2.2

View File

@@ -29,7 +29,7 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
override predicate isSource(Instruction source) {
exists(Function func |
// Rule out FPs caused by extraction errors.
not any(ErrorExpr e).getEnclosingFunction() = func and
not func.hasErrors() and
not intentionallyReturnsStackPointer(func) and
func = source.getEnclosingFunction()
|

View File

@@ -65,6 +65,7 @@ predicate isSinkImpl(Instruction sink, VariableAccess va) {
exists(LoadInstruction load |
va = load.getUnconvertedResultExpression() and
not va = commonException() and
not va.getTarget().(LocalVariable).getFunction().hasErrors() and
sink = load.getSourceValue()
)
}

View File

@@ -24,7 +24,7 @@ predicate instructionHasVariable(VariableAddressInstruction vai, StackVariable v
// Pointer-to-member types aren't properly handled in the dbscheme.
not vai.getResultType() instanceof PointerToMemberType and
// Rule out FPs caused by extraction errors.
not any(ErrorExpr e).getEnclosingFunction() = f
not f.hasErrors()
}
/**

View File

@@ -13,23 +13,85 @@
*/
import cpp
import semmle.code.cpp.controlflow.Guards
class WideCharPointerType extends PointerType {
WideCharPointerType() { this.getBaseType() instanceof WideCharType }
}
/**
* Given type `t`, recurses through and returns all
* intermediate base types, including `t`.
*/
Type getABaseType(Type t) {
result = t
or
result = getABaseType(t.(DerivedType).getBaseType())
or
result = getABaseType(t.(TypedefType).getBaseType())
}
/**
* A type that may also be `CharPointerType`, but that are likely used as arbitrary buffers.
*/
class UnlikelyToBeAStringType extends Type {
UnlikelyToBeAStringType() {
this.(PointerType).getBaseType().(CharType).isUnsigned() or
this.(PointerType).getBaseType().getName().toLowerCase().matches("%byte") or
this.getName().toLowerCase().matches("%byte") or
this.(PointerType).getBaseType().hasName("uint8_t")
exists(Type targ | getABaseType(this) = targ |
// NOTE: not using CharType isUnsigned, but rather look for any explicitly declared unsigned
// char types. Assuming these are used for buffers, not strings.
targ.(CharType).getName().toLowerCase().matches("unsigned%") or
targ.getName().toLowerCase().matches(["uint8_t", "%byte%"])
)
}
}
// Types that can be wide depending on the UNICODE macro
// see https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
class UnicodeMacroDependentWidthType extends Type {
UnicodeMacroDependentWidthType() {
exists(Type targ | getABaseType(this) = targ |
targ.getName() in [
"LPCTSTR",
"LPTSTR",
"PCTSTR",
"PTSTR",
"TBYTE",
"TCHAR"
]
)
}
}
class UnicodeMacro extends Macro {
UnicodeMacro() { this.getName().toLowerCase().matches("%unicode%") }
}
class UnicodeMacroInvocation extends MacroInvocation {
UnicodeMacroInvocation() { this.getMacro() instanceof UnicodeMacro }
}
/**
* Holds when a expression whose type is UnicodeMacroDependentWidthType and
* is observed to be guarded by a check involving a bitwise-and operation
* with a UnicodeMacroInvocation.
* Such expressions are assumed to be checked dynamically, i.e.,
* the flag would indicate if UNICODE typing is set correctly to allow
* or disallow a widening cast.
*/
predicate isLikelyDynamicallyChecked(Expr e) {
e.getType() instanceof UnicodeMacroDependentWidthType and
exists(GuardCondition gc, BitwiseAndExpr bai, UnicodeMacroInvocation umi |
bai.getAnOperand() = umi.getExpr()
|
// bai == 0 is false when reaching `e.getBasicBlock()`.
// That is, bai != 0 when reaching `e.getBasicBlock()`.
gc.ensuresEq(bai, 0, e.getBasicBlock(), false)
or
// bai == k and k != 0 is true when reaching `e.getBasicBlock()`.
gc.ensuresEq(bai, any(int k | k != 0), e.getBasicBlock(), true)
)
}
from Expr e1, Cast e2
where
e2 = e1.getConversion() and
@@ -42,7 +104,11 @@ where
not e1.getType() instanceof UnlikelyToBeAStringType and
// Avoid castings from 'new' expressions as typically these will be safe
// Example: `__Type* ret = reinterpret_cast<__Type*>(New(m_pmo) char[num * sizeof(__Type)]);`
not exists(NewOrNewArrayExpr newExpr | newExpr.getAChild*() = e1)
not exists(NewOrNewArrayExpr newExpr | newExpr.getAChild*() = e1) and
// Avoid cases where the cast is guarded by a check to determine if
// unicode encoding is enabled in such a way to disallow the dangerous cast
// at runtime.
not isLikelyDynamicallyChecked(e1)
select e1,
"Conversion from " + e1.getType().toString() + " to " + e2.getType().toString() +
". Use of invalid string can lead to undefined behavior."

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* The `cpp/incorrect-string-type-conversion` query now produces fewer false positives caused by failure to detect byte arrays.
* The `cpp/incorrect-string-type-conversion` query now produces fewer false positives caused by failure to recognize dynamic checks prior to possible dangerous widening.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Fixed false positives in the `cpp/uninitialized-local` ("Potentially uninitialized local variable") query if there are extraction errors in the function.

View File

@@ -0,0 +1,5 @@
## 1.2.4
### Minor Analysis Improvements
* Fixed false positives in the `cpp/wrong-number-format-arguments` ("Too few arguments to formatting function") query when the formatting function has been declared implicitly.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.2.3
lastReleaseVersion: 1.2.4

View File

@@ -0,0 +1,34 @@
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
<qhelp>
<overview>
<p>
Disabling verification of the SSL certificate allows man-in-the-middle attacks. A SSL
connection is vulnerable to man-in-the-middle attacks if the certification is not checked
properly. If the peer or the host's certificate verification is not verified, the underlying
SSL communication is insecure.</p>
</overview>
<recommendation>
<p>It is recommended that all communications be done post verification of the host as well as
the
peer.</p>
</recommendation>
<example>
<p>The following snippet disables certification verification by setting the value of <code>
CURLOPT_SSL_VERIFYHOST</code> and <code>CURLOPT_SSL_VERIFYHOST</code> to <code>0</code>:</p>
<sample src="CurlSSLBad.cpp" />
<p>This is bad as the certificates are not verified any more. This can be easily fixed by
setting the values of the options to <code>2</code>. </p>
<sample src="CurlSSLGood.cpp" />
</example>
<references>
<li> Curl Documentation:<a href="https://curl.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html">
CURLOPT_SSL_VERIFYHOST</a></li>
<li> Curl Documentation:<a href="https://curl.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html">
CURLOPT_SSL_VERIFYPEER</a></li>
<li> Related CVE: <a href="https://github.com/advisories/GHSA-5r3h-c3r7-9w4h"> CVE-2022-33684</a></li>
<li> Related security advisory: <a
href="https://huntr.com/bounties/42325662-6329-4e04-875a-49e2f5d69f78">
openframeworks/openframeworks
</a></li>
</references>
</qhelp>

View File

@@ -0,0 +1,39 @@
/**
* @name Disabled certifcate verification
* @description Disabling SSL certificate verification of host or peer could expose the communication to man-in-the-middle(MITM) attacks.
* @kind problem
* @problem.severity warning
* @id cpp/curl-disabled-ssl
* @tags security
* external/cwe/cwe-295
*/
import cpp
import semmle.code.cpp.dataflow.new.TaintTracking
/** Models the `curl_easy_setopt` function call */
private class CurlSetOptCall extends FunctionCall {
CurlSetOptCall() {
exists(FunctionCall fc, Function f |
f.hasGlobalOrStdName("curl_easy_setopt") and
fc.getTarget() = f
|
this = fc
)
}
}
/** Models an access to any enum constant which could affect SSL verification */
private class CurlVerificationConstant extends EnumConstantAccess {
CurlVerificationConstant() {
exists(EnumConstant e | e.getName() = ["CURLOPT_SSL_VERIFYHOST", "CURLOPT_SSL_VERIFYPEER"] |
e.getAnAccess() = this
)
}
}
from CurlSetOptCall c
where
c.getArgument(1) = any(CurlVerificationConstant v) and
c.getArgument(2).getValue() = "0"
select c, "This call disables Secure Socket Layer and could potentially lead to MITM attacks"

View File

@@ -0,0 +1,9 @@
string host = "codeql.com"
void bad(void) {
std::unique_ptr<CURL, void(*)(CURL*)> curl =
std::unique_ptr<CURL, void(*)(CURL*)>(curl_easy_init(), curl_easy_cleanup);
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl.get(), CURLOPT_URL, host.c_str());
curl_easy_perform(curl.get());
}

View File

@@ -0,0 +1,9 @@
string host = "codeql.com"
void good(void) {
std::unique_ptr<CURL, void(*)(CURL*)> curl =
std::unique_ptr<CURL, void(*)(CURL*)>(curl_easy_init(), curl_easy_cleanup);
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, 2);
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, 2);
curl_easy_setopt(curl.get(), CURLOPT_URL, host.c_str());
curl_easy_perform(curl.get());
}

View File

@@ -49,7 +49,7 @@ predicate functionsMissingReturnStmt(Function f, ControlFlowNode blame) {
predicate functionImperfectlyExtracted(Function f) {
exists(CompilerError e | f.getBlock().getLocation().subsumes(e.getLocation()))
or
exists(ErrorExpr ee | ee.getEnclosingFunction() = f)
f.hasErrors()
or
count(f.getType()) > 1
or

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 1.2.3
version: 1.2.5-dev
groups:
- cpp
- queries

View File

@@ -0,0 +1,43 @@
#include "../../../../../library-tests/string_concat/stl.h"
namespace std{
struct CURL {};
typedef CURL curl;
enum curl_constant{
CURLOPT_URL,
CURLOPT_SSL_VERIFYHOST,
CURLOPT_SSL_VERIFYPEER
};
CURL *curl_easy_init();
void curl_easy_cleanup(CURL *handle);
void curl_easy_perform(CURL *handle);
void curl_easy_setopt(CURL *handle, curl_constant param, int p);
void curl_easy_setopt(CURL *handle, curl_constant param, char* p);
}
using namespace std;
char host[] = "codeql.com";
void bad(void) {
std::unique_ptr<CURL> curl = std::unique_ptr<CURL>(curl_easy_init());
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl.get(), CURLOPT_URL, host);
curl_easy_perform(curl.get());
}
void good(void) {
std::unique_ptr<CURL> curl = std::unique_ptr<CURL>(curl_easy_init());
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, 2);
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, 2);
curl_easy_setopt(curl.get(), CURLOPT_URL, host);
curl_easy_perform(curl.get());
}
int main(int c, char** argv){
bad();
good();
}

View File

@@ -0,0 +1,2 @@
| CurlSSL.cpp:25:2:25:17 | call to curl_easy_setopt | This call disables Secure Socket Layer and could potentially lead to MITM attacks |
| CurlSSL.cpp:26:2:26:17 | call to curl_easy_setopt | This call disables Secure Socket Layer and could potentially lead to MITM attacks |

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-295/CurlSSL.ql

View File

@@ -3,20 +3,20 @@ failures
edges
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:10 |
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:2 |
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:2 Sink:MaD:6 |
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:2 Sink:MaD:6 |
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction |
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:100:64:100:71 | *send_str | provenance | TaintFunction |
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | |
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:6 |
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:6 |
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | |
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:10 |
| test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | test.cpp:4:5:4:11 | [summary] to write: ReturnValue in ymlStep | provenance | MaD:644 |
| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:7:10:7:18 | call to ymlSource | provenance | Src:MaD:642 |
| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:643 |
| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:11:10:11:10 | x | provenance | Sink:MaD:643 |
| test.cpp:7:10:7:18 | call to ymlSource | test.cpp:13:18:13:18 | x | provenance | |
| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:13:10:13:16 | call to ymlStep | provenance | |
| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:643 |
| test.cpp:13:10:13:16 | call to ymlStep | test.cpp:15:10:15:10 | y | provenance | Sink:MaD:643 |
| test.cpp:13:18:13:18 | x | test.cpp:4:5:4:11 | [summary param] 0 in ymlStep | provenance | |
| test.cpp:13:18:13:18 | x | test.cpp:13:10:13:16 | call to ymlStep | provenance | MaD:644 |
nodes

View File

@@ -2,25 +2,168 @@
| file://:0:0:0:0 | (unnamed parameter 0) | false |
| file://:0:0:0:0 | __super | false |
| file://:0:0:0:0 | __va_list_tag | false |
| file://:0:0:0:0 | decltype([...](...){...}) | false |
| file://:0:0:0:0 | operator= | false |
| file://:0:0:0:0 | operator= | false |
| test.cpp:0:0:0:0 | test.cpp | false |
| test.cpp:2:1:2:61 | #define FOO class S{int i; void f(void) { int j; return; } }; | false |
| test.cpp:2:1:2:68 | #define CLASS_DECL class S{int i; void f(void) { int j; return; } }; | false |
| test.cpp:4:1:4:1 | S | false |
| test.cpp:4:1:4:1 | declaration of S | false |
| test.cpp:4:1:4:1 | declaration of operator= | false |
| test.cpp:4:1:4:1 | declaration of operator= | false |
| test.cpp:4:1:4:1 | operator= | false |
| test.cpp:4:1:4:1 | operator= | false |
| test.cpp:4:1:4:3 | FOO | false |
| test.cpp:4:1:4:3 | S | false |
| test.cpp:4:1:4:3 | declaration | true |
| test.cpp:4:1:4:3 | definition of S | true |
| test.cpp:4:1:4:3 | definition of f | true |
| test.cpp:4:1:4:3 | definition of i | true |
| test.cpp:4:1:4:3 | definition of j | true |
| test.cpp:4:1:4:3 | f | false |
| test.cpp:4:1:4:3 | i | false |
| test.cpp:4:1:4:3 | j | true |
| test.cpp:4:1:4:3 | return ... | true |
| test.cpp:4:1:4:3 | { ... } | true |
| test.cpp:4:1:4:10 | CLASS_DECL | false |
| test.cpp:4:1:4:10 | S | false |
| test.cpp:4:1:4:10 | declaration | true |
| test.cpp:4:1:4:10 | definition of S | true |
| test.cpp:4:1:4:10 | definition of f | true |
| test.cpp:4:1:4:10 | definition of i | true |
| test.cpp:4:1:4:10 | definition of j | true |
| test.cpp:4:1:4:10 | f | false |
| test.cpp:4:1:4:10 | i | false |
| test.cpp:4:1:4:10 | j | true |
| test.cpp:4:1:4:10 | return ... | true |
| test.cpp:4:1:4:10 | { ... } | true |
| test.cpp:6:1:6:42 | #define FUNCTION_DECL void f1() { int k; } | false |
| test.cpp:8:1:8:13 | FUNCTION_DECL | false |
| test.cpp:8:1:8:13 | declaration | true |
| test.cpp:8:1:8:13 | definition of f1 | true |
| test.cpp:8:1:8:13 | definition of k | true |
| test.cpp:8:1:8:13 | f1 | false |
| test.cpp:8:1:8:13 | k | true |
| test.cpp:8:1:8:13 | return ... | true |
| test.cpp:8:1:8:13 | { ... } | true |
| test.cpp:10:1:10:33 | #define VARIABLE_DECL int v1 = 1; | false |
| test.cpp:12:1:12:13 | 1 | true |
| test.cpp:12:1:12:13 | VARIABLE_DECL | false |
| test.cpp:12:1:12:13 | definition of v1 | true |
| test.cpp:12:1:12:13 | initializer for v1 | true |
| test.cpp:12:1:12:13 | v1 | true |
| test.cpp:14:1:14:35 | #define TYPE_DECL_1 typedef int t1; | false |
| test.cpp:16:1:16:11 | TYPE_DECL_1 | false |
| test.cpp:16:1:16:11 | declaration of t1 | true |
| test.cpp:16:1:16:11 | t1 | false |
| test.cpp:18:1:18:35 | #define TYPE_DECL_2 using t2 = int; | false |
| test.cpp:20:1:20:11 | TYPE_DECL_2 | false |
| test.cpp:20:1:20:11 | declaration of t2 | true |
| test.cpp:20:1:20:11 | t2 | false |
| test.cpp:22:1:22:47 | #define NAMESPACE_DECL namespace ns { int v2; } | false |
| test.cpp:24:1:24:14 | NAMESPACE_DECL | false |
| test.cpp:24:1:24:14 | definition of v2 | true |
| test.cpp:24:1:24:14 | ns | false |
| test.cpp:24:1:24:14 | ns | false |
| test.cpp:24:1:24:14 | v2 | true |
| test.cpp:26:1:26:43 | #define USING_NAMESPACE using namespace ns; | false |
| test.cpp:28:1:28:34 | #define ENUM_CONSTANT enum_element | false |
| test.cpp:30:12:30:21 | definition of enum_class | false |
| test.cpp:30:12:30:21 | enum_class | false |
| test.cpp:30:25:30:37 | ENUM_CONSTANT | false |
| test.cpp:30:25:30:37 | enum_element | false |
| test.cpp:32:1:32:41 | #define USING_ENUM using enum enum_class; | false |
| test.cpp:34:1:34:10 | USING_ENUM | false |
| test.cpp:34:1:34:10 | using enum enum_class | false |
| test.cpp:36:1:36:48 | #define STATIC_ASSERT static_assert(1 == 1, ""); | false |
| test.cpp:38:1:38:13 | 1 | true |
| test.cpp:38:1:38:13 | 1 | true |
| test.cpp:38:1:38:13 | ... == ... | true |
| test.cpp:38:1:38:13 | STATIC_ASSERT | false |
| test.cpp:38:1:38:13 | static_assert(..., "") | false |
| test.cpp:40:1:40:42 | #define ATTRIBUTE [[nodiscard("reason1")]] | false |
| test.cpp:42:1:42:9 | ATTRIBUTE | false |
| test.cpp:42:1:42:9 | nodiscard | false |
| test.cpp:42:1:42:9 | reason1 | false |
| test.cpp:42:1:42:9 | reason1 | true |
| test.cpp:43:5:43:6 | declaration of f2 | false |
| test.cpp:43:5:43:6 | f2 | false |
| test.cpp:45:1:45:31 | #define ATTRIBUTE_ARG "reason2" | false |
| test.cpp:47:3:47:11 | nodiscard | false |
| test.cpp:47:13:47:25 | ATTRIBUTE_ARG | false |
| test.cpp:47:13:47:25 | reason2 | false |
| test.cpp:47:13:47:25 | reason2 | true |
| test.cpp:48:5:48:6 | declaration of f3 | false |
| test.cpp:48:5:48:6 | f3 | false |
| test.cpp:50:1:50:16 | #define TYPE int | false |
| test.cpp:52:1:52:4 | TYPE | false |
| test.cpp:52:6:52:7 | definition of v3 | true |
| test.cpp:52:6:52:7 | v3 | true |
| test.cpp:52:11:52:11 | 1 | false |
| test.cpp:52:11:52:11 | initializer for v3 | false |
| test.cpp:54:1:54:29 | #define DERIVATION : public S | false |
| test.cpp:56:7:56:7 | T | false |
| test.cpp:56:7:56:7 | T | false |
| test.cpp:56:7:56:7 | declaration of T | false |
| test.cpp:56:7:56:7 | declaration of operator= | false |
| test.cpp:56:7:56:7 | declaration of operator= | false |
| test.cpp:56:7:56:7 | definition of T | false |
| test.cpp:56:7:56:7 | operator= | false |
| test.cpp:56:7:56:7 | operator= | false |
| test.cpp:56:9:56:18 | DERIVATION | false |
| test.cpp:56:9:56:18 | derivation | false |
| test.cpp:58:1:58:31 | #define FRIEND friend int f3(); | false |
| test.cpp:60:7:60:7 | U | false |
| test.cpp:60:7:60:7 | declaration of operator= | false |
| test.cpp:60:7:60:7 | declaration of operator= | false |
| test.cpp:60:7:60:7 | definition of U | false |
| test.cpp:60:7:60:7 | operator= | false |
| test.cpp:60:7:60:7 | operator= | false |
| test.cpp:61:3:61:8 | FRIEND | false |
| test.cpp:61:3:61:8 | U's friend | false |
| test.cpp:64:1:64:24 | #define NAME_QUAL_1 ns:: | false |
| test.cpp:66:1:66:22 | #define NAME_QUAL_2 ns | false |
| test.cpp:68:1:68:19 | #define LOCAL_VAR m | false |
| test.cpp:70:6:70:7 | definition of f4 | false |
| test.cpp:70:6:70:7 | f4 | false |
| test.cpp:70:11:76:1 | { ... } | false |
| test.cpp:71:5:71:8 | ns:: | false |
| test.cpp:71:5:71:15 | NAME_QUAL_1 | false |
| test.cpp:71:5:71:18 | v2 | false |
| test.cpp:71:5:71:19 | ExprStmt | false |
| test.cpp:72:5:72:8 | ns:: | false |
| test.cpp:72:5:72:15 | NAME_QUAL_2 | false |
| test.cpp:72:5:72:21 | v2 | false |
| test.cpp:72:5:72:22 | ExprStmt | false |
| test.cpp:73:5:73:23 | declaration | false |
| test.cpp:73:9:73:17 | LOCAL_VAR | false |
| test.cpp:73:9:73:17 | definition of m | true |
| test.cpp:73:9:73:17 | m | true |
| test.cpp:73:20:73:22 | 42 | false |
| test.cpp:73:20:73:22 | initializer for m | false |
| test.cpp:74:5:74:41 | declaration | false |
| test.cpp:74:10:74:10 | definition of l | false |
| test.cpp:74:10:74:10 | l | false |
| test.cpp:74:13:74:40 | [...](...){...} | false |
| test.cpp:74:13:74:40 | initializer for l | false |
| test.cpp:74:13:74:40 | {...} | false |
| test.cpp:74:14:74:14 | (unnamed constructor) | false |
| test.cpp:74:14:74:14 | (unnamed constructor) | false |
| test.cpp:74:14:74:14 | (unnamed constructor) | false |
| test.cpp:74:14:74:14 | declaration of (unnamed constructor) | false |
| test.cpp:74:14:74:14 | declaration of (unnamed constructor) | false |
| test.cpp:74:14:74:14 | definition of (unnamed constructor) | false |
| test.cpp:74:14:74:14 | definition of operator= | false |
| test.cpp:74:14:74:14 | operator= | false |
| test.cpp:74:15:74:15 | definition of m | false |
| test.cpp:74:15:74:15 | m | false |
| test.cpp:74:15:74:15 | m | false |
| test.cpp:74:15:74:23 | LOCAL_VAR | false |
| test.cpp:74:15:74:23 | m | true |
| test.cpp:74:25:74:25 | definition of operator() | false |
| test.cpp:74:25:74:25 | operator() | false |
| test.cpp:74:28:74:40 | { ... } | false |
| test.cpp:74:30:74:38 | return ... | false |
| test.cpp:74:37:74:37 | (int)... | false |
| test.cpp:75:5:75:5 | (const lambda [] type at line 74, col. 14)... | false |
| test.cpp:75:5:75:5 | l | false |
| test.cpp:75:5:75:8 | ExprStmt | false |
| test.cpp:75:6:75:6 | call to operator() | false |
| test.cpp:76:1:76:1 | return ... | false |
| test.cpp:78:1:78:15 | #define ID(x) x | false |
| test.cpp:79:1:79:23 | #define NESTED(x) ID(x) | false |
| test.cpp:80:5:80:6 | definition of v4 | false |
| test.cpp:80:5:80:6 | v4 | false |
| test.cpp:80:10:80:18 | ID(x) | false |
| test.cpp:80:10:80:18 | NESTED(x) | false |
| test.cpp:80:17:80:17 | 1 | true |
| test.cpp:80:17:80:17 | initializer for v4 | true |
| test.cpp:82:1:82:39 | // semmle-extractor-options: -std=c++20 | false |

View File

@@ -1,5 +1,82 @@
#define FOO class S{int i; void f(void) { int j; return; } };
#define CLASS_DECL class S{int i; void f(void) { int j; return; } };
FOO
CLASS_DECL
#define FUNCTION_DECL void f1() { int k; }
FUNCTION_DECL
#define VARIABLE_DECL int v1 = 1;
VARIABLE_DECL
#define TYPE_DECL_1 typedef int t1;
TYPE_DECL_1
#define TYPE_DECL_2 using t2 = int;
TYPE_DECL_2
#define NAMESPACE_DECL namespace ns { int v2; }
NAMESPACE_DECL
#define USING_NAMESPACE using namespace ns;
#define ENUM_CONSTANT enum_element
enum class enum_class { ENUM_CONSTANT };
#define USING_ENUM using enum enum_class;
USING_ENUM
#define STATIC_ASSERT static_assert(1 == 1, "");
STATIC_ASSERT
#define ATTRIBUTE [[nodiscard("reason1")]]
ATTRIBUTE
int f2();
#define ATTRIBUTE_ARG "reason2"
[[nodiscard(ATTRIBUTE_ARG)]]
int f3();
#define TYPE int
TYPE v3 = 1;
#define DERIVATION : public S
class T DERIVATION {};
#define FRIEND friend int f3();
class U {
FRIEND
};
#define NAME_QUAL_1 ns::
#define NAME_QUAL_2 ns
#define LOCAL_VAR m
void f4() {
NAME_QUAL_1 v2;
NAME_QUAL_2 :: v2;
int LOCAL_VAR = 42;
auto l = [LOCAL_VAR]() { return m; };
l();
}
#define ID(x) x
#define NESTED(x) ID(x)
int v4 = NESTED(1);
// semmle-extractor-options: -std=c++20

View File

@@ -10,3 +10,4 @@
| test.c:15:2:15:7 | call to printf | Format for printf expects 3 arguments but given 2 |
| test.c:19:2:19:7 | call to printf | Format for printf expects 2 arguments but given 1 |
| test.c:29:3:29:8 | call to printf | Format for printf expects 2 arguments but given 1 |
| test.c:53:2:53:10 | call to my_logger | Format for my_logger expects 3 arguments but given 2 |

View File

@@ -44,3 +44,6 @@ void test_custom_printf2()
printf("", "%i %i", 100, 200); // GOOD
printf("%i %i", "" ); // GOOD
}
extern "C" void my_logger(int param, char *fmt, ...) __attribute__((format(printf, 2, 3))) {}

View File

@@ -46,4 +46,12 @@ void test(int i, const char *str)
printf("%Y", 1, 2); // GOOD (unknown format character, this might be correct)
printf("%1.1Y", 1, 2); // GOOD (unknown format character, this might be correct)
printf("%*.*Y", 1, 2); // GOOD (unknown format character, this might be correct)
// Implicit logger function declaration
my_logger(0, "%i %i %i %i %i %i\n", 1, 2, 3, 4, 5, 6); // GOOD
my_logger(0, "%i %i %i\n", 1, 2, 3); // GOOD
my_logger(0, "%i %i %i\n", 1, 2); // BAD (too few format arguments)
}
// A spurious definition of my_logger
extern void my_logger(int param, char *fmt, int, int, int, int, int);

View File

@@ -1,5 +1,6 @@
edges
nodes
| errors.cpp:13:7:13:7 | definition of x | semmle.label | definition of x |
| test.cpp:11:6:11:8 | definition of foo | semmle.label | definition of foo |
| test.cpp:111:6:111:8 | definition of foo | semmle.label | definition of foo |
| test.cpp:226:7:226:7 | definition of x | semmle.label | definition of x |
@@ -14,6 +15,7 @@ nodes
| test.cpp:472:6:472:6 | definition of x | semmle.label | definition of x |
| test.cpp:479:6:479:6 | definition of x | semmle.label | definition of x |
#select
| errors.cpp:14:18:14:18 | x | errors.cpp:13:7:13:7 | definition of x | errors.cpp:13:7:13:7 | definition of x | The variable $@ may not be initialized at this access. | errors.cpp:13:7:13:7 | x | x |
| test.cpp:12:6:12:8 | foo | test.cpp:11:6:11:8 | definition of foo | test.cpp:11:6:11:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:11:6:11:8 | foo | foo |
| test.cpp:113:6:113:8 | foo | test.cpp:111:6:111:8 | definition of foo | test.cpp:111:6:111:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:111:6:111:8 | foo | foo |
| test.cpp:227:3:227:3 | x | test.cpp:226:7:226:7 | definition of x | test.cpp:226:7:226:7 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:226:7:226:7 | x | x |

View File

@@ -0,0 +1,15 @@
// semmle-extractor-options: --expect_errors
int f1() {
int x;
initialize(&x); // error expression - initialize() is not defined
return x; // GOOD - assume x is initialized
}
void * operator new(unsigned long, bool);
void operator delete(void*, bool);
int f2() {
int x;
new(true) int (x); // BAD, ignore implicit error expression
}

View File

@@ -53,4 +53,59 @@ void NonStringFalsePositiveTest2(unsigned char* buffer)
{
wchar_t *lpWchar = NULL;
lpWchar = (LPWSTR)buffer; // Possible False Positive
}
}
typedef unsigned char BYTE;
using FOO = BYTE*;
void NonStringFalsePositiveTest3(FOO buffer)
{
wchar_t *lpWchar = NULL;
lpWchar = (LPWSTR)buffer; // GOOD
}
#define UNICODE 0x8
// assume EMPTY_MACRO is tied to if UNICODE is enabled
#ifdef EMPTY_MACRO
typedef WCHAR* LPTSTR;
#else
typedef char* LPTSTR;
#endif
void CheckedConversionFalsePositiveTest3(unsigned short flags, LPTSTR buffer)
{
wchar_t *lpWchar = NULL;
if(flags & UNICODE)
lpWchar = (LPWSTR)buffer; // GOOD
else
lpWchar = (LPWSTR)buffer; // BUG
if((flags & UNICODE) == 0x8)
lpWchar = (LPWSTR)buffer; // GOOD
else
lpWchar = (LPWSTR)buffer; // BUG
if((flags & UNICODE) != 0x8)
lpWchar = (LPWSTR)buffer; // BUG
else
lpWchar = (LPWSTR)buffer; // GOOD
// Bad operator precedence
if(flags & UNICODE == 0x8)
lpWchar = (LPWSTR)buffer; // BUG
else
lpWchar = (LPWSTR)buffer; // BUG
if((flags & UNICODE) != 0)
lpWchar = (LPWSTR)buffer; // GOOD
else
lpWchar = (LPWSTR)buffer; // BUG
if((flags & UNICODE) == 0)
lpWchar = (LPWSTR)buffer; // BUG
else
lpWchar = (LPWSTR)buffer; // GOOD
lpWchar = (LPWSTR)buffer; // BUG
}

View File

@@ -3,3 +3,11 @@
| WcharCharConversion.cpp:24:22:24:27 | lpChar | Conversion from char * to wchar_t *. Use of invalid string can lead to undefined behavior. |
| WcharCharConversion.cpp:26:23:26:28 | lpChar | Conversion from char * to LPCWSTR. Use of invalid string can lead to undefined behavior. |
| WcharCharConversion.cpp:27:17:27:22 | lpChar | Conversion from char * to LPWSTR. Use of invalid string can lead to undefined behavior. |
| WcharCharConversion.cpp:82:21:82:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. |
| WcharCharConversion.cpp:87:21:87:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. |
| WcharCharConversion.cpp:90:21:90:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. |
| WcharCharConversion.cpp:96:21:96:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. |
| WcharCharConversion.cpp:98:21:98:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. |
| WcharCharConversion.cpp:103:21:103:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. |
| WcharCharConversion.cpp:106:21:106:26 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. |
| WcharCharConversion.cpp:110:20:110:25 | buffer | Conversion from LPTSTR to LPWSTR. Use of invalid string can lead to undefined behavior. |

1
csharp/.gitignore vendored
View File

@@ -11,7 +11,6 @@ csharp.log
*.tlog
.vs
*.user
.vscode/launch.json
extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json
paket-files/

65
csharp/.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,65 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "C#: Standalone Debug",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "dotnet: build",
"program": "${workspaceFolder}/extractor/Semmle.Extraction.CSharp.Standalone/bin/Debug/net8.0/Semmle.Extraction.CSharp.Standalone.dll",
"args": [],
// Set the path to the folder that should be extracted:
"cwd": "${workspaceFolder}/ql/test/library-tests/standalone/standalonemode",
"env": {
"CODEQL_THREADS": "1",
"CODEQL_EXTRACTOR_CSHARP_OPTION_LOGGING_VERBOSITY": "progress+++",
"CODEQL_EXTRACTOR_CSHARP_OPTION_TRAP_COMPRESSION": "NONE",
},
"stopAtEntry": true,
"console": "internalConsole",
"justMyCode": false,
"symbolOptions": {
"searchPaths": [],
"searchMicrosoftSymbolServer": true,
"searchNuGetOrgSymbolServer": true
},
"sourceLinkOptions": {
"*": {
"enabled": true
}
},
"suppressJITOptimizations": true
},
{
"name": "C#: Autobuild Debug",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "dotnet: build",
"program": "${workspaceFolder}/autobuilder/Semmle.Autobuild.CSharp/bin/Debug/net8.0/Semmle.Autobuild.CSharp.dll",
// Set the path to the folder that should be extracted:
"cwd": "${workspaceFolder}/ql/integration-tests/all-platforms/autobuild",
"stopAtEntry": true,
"args": [],
"env": {
// The below folders need to exist before debugging
"CODEQL_EXTRACTOR_CSHARP_TRAP_DIR": "${workspaceFolder}/ql/integration-tests/DB",
"CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR": "${workspaceFolder}/ql/integration-tests/DB",
"CODEQL_EXTRACTOR_CSHARP_DIAGNOSTIC_DIR": "${workspaceFolder}/ql/integration-tests/DB",
"CODEQL_EXTRACTOR_CSHARP_SCRATCH_DIR": "${workspaceFolder}/ql/integration-tests/DB",
}
},
{
"name": "C#: Binary Log Debug",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "dotnet: build",
"program": "${workspaceFolder}/extractor/Semmle.Extraction.CSharp.Driver/bin/Debug/net8.0/Semmle.Extraction.CSharp.Driver.dll",
"stopAtEntry": true,
"args": [
"--binlog",
"${workspaceFolder}/ql/integration-tests/all-platforms/binlog/test.binlog"
],
"env": {}
},
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Add `cil` and `dotnet` related relations and types.
compatibility: backwards

View File

@@ -144,50 +144,5 @@ namespace Semmle.Extraction.CSharp.Entities
public override bool NeedsPopulation => Context.Defines(Symbol);
public Extraction.Entities.Location Location => Context.CreateLocation(ReportingLocation);
protected void PopulateMetadataHandle(TextWriter trapFile)
{
var handle = MetadataHandle;
if (handle.HasValue)
trapFile.metadata_handle(this, Location, MetadataTokens.GetToken(handle.Value));
}
private static System.Reflection.PropertyInfo? GetPropertyInfo(object o, string name)
{
return o.GetType().GetProperty(name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetProperty);
}
public Handle? MetadataHandle
{
get
{
var handleProp = GetPropertyInfo(Symbol, "Handle");
object handleObj = Symbol;
if (handleProp is null)
{
var underlyingSymbolProp = GetPropertyInfo(Symbol, "UnderlyingSymbol");
if (underlyingSymbolProp?.GetValue(Symbol) is object underlying)
{
handleProp = GetPropertyInfo(underlying, "Handle");
handleObj = underlying;
}
}
if (handleProp is not null)
{
switch (handleProp.GetValue(handleObj))
{
case MethodDefinitionHandle md: return md;
case TypeDefinitionHandle td: return td;
case PropertyDefinitionHandle pd: return pd;
case FieldDefinitionHandle fd: return fd;
}
}
return null;
}
}
}
}

View File

@@ -26,7 +26,6 @@ namespace Semmle.Extraction.CSharp.Entities
public override void Populate(TextWriter trapFile)
{
PopulateMetadataHandle(trapFile);
PopulateAttributes();
ContainingType!.PopulateGenerics();
PopulateNullability(trapFile, Symbol.GetAnnotatedType());

View File

@@ -64,7 +64,7 @@ namespace Semmle.Extraction.CSharp.Entities
}
catch (Exception exc)
{
Context.ExtractionError($"Couldn't read file: {originalPath}. {exc.Message}", null, null, exc.StackTrace);
Context.ExtractionError($"Couldn't read file: {originalPath}. {exc.Message}", null, null, exc.StackTrace, Semmle.Util.Logging.Severity.Warning);
}
}

View File

@@ -51,6 +51,7 @@ namespace Semmle.Extraction.CSharp.Entities
}
}
PopulateAttributes();
PopulateModifiers(trapFile);
BindComments();

View File

@@ -360,7 +360,6 @@ namespace Semmle.Extraction.CSharp.Entities
PopulateParameters();
PopulateMethodBody(trapFile);
PopulateGenerics(trapFile);
PopulateMetadataHandle(trapFile);
PopulateNullability(trapFile, Symbol.GetAnnotatedReturnType());
}

View File

@@ -34,7 +34,6 @@ namespace Semmle.Extraction.CSharp.Entities
public override void Populate(TextWriter trapFile)
{
PopulateMetadataHandle(trapFile);
PopulateAttributes();
PopulateModifiers(trapFile);
BindComments();

View File

@@ -77,7 +77,6 @@ namespace Semmle.Extraction.CSharp.Entities
protected void PopulateType(TextWriter trapFile, bool constructUnderlyingTupleType = false)
{
PopulateMetadataHandle(trapFile);
PopulateAttributes();
trapFile.Write("types(");

View File

@@ -233,9 +233,6 @@ namespace Semmle.Extraction.CSharp
internal static void localvars(this TextWriter trapFile, LocalVariable key, VariableKind kind, string name, int @var, Type type, Expression expr) =>
trapFile.WriteTuple("localvars", key, (int)kind, name, @var, type, expr);
public static void metadata_handle(this TextWriter trapFile, IEntity entity, Location assembly, int handleValue) =>
trapFile.WriteTuple("metadata_handle", entity, assembly, handleValue);
internal static void method_location(this TextWriter trapFile, Method method, Location location) =>
trapFile.WriteTuple("method_location", method, location);

View File

@@ -1,3 +1,7 @@
## 1.7.26
No user-facing changes.
## 1.7.25
No user-facing changes.

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.7.25
lastReleaseVersion: 1.7.26

View File

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

View File

@@ -1,3 +1,7 @@
## 1.7.26
No user-facing changes.
## 1.7.25
No user-facing changes.

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.7.25
lastReleaseVersion: 1.7.26

View File

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

View File

@@ -61,8 +61,3 @@ query predicate preBasicBlockConsistency(ControlFlowElement cfe1, ControlFlowEle
bbIntraSuccInconsistency(cfe1, cfe2) and
s = "intra succ inconsistency"
}
query predicate multipleToString(Node n, string s) {
s = strictconcat(n.toString(), ",") and
strictcount(n.toString()) > 1
}

View File

@@ -1,3 +1,19 @@
## 3.0.0
### Breaking Changes
* C#: Add support for MaD directly on properties and indexers using *attributes*. Using `Attribute.Getter` or `Attribute.Setter` in the model `ext` field applies the model to the getter or setter for properties and indexers. Prior to this change `Attribute` models unintentionally worked for property setters (if the property is decorated with the matching attribute). That is, a model that uses the `Attribute` feature directly on a property for a property setter needs to be changed to `Attribute.Setter`.
* C#: Remove all CIL tables and related QL library functionality.
### Deprecated APIs
* The class `ThreatModelFlowSource` has been renamed to `ActiveThreatModelSource` to more clearly reflect it only contains the currently active threat model sources. `ThreatModelFlowSource` has been marked as deprecated.
### Minor Analysis Improvements
* `DataFlow::Node` instances are no longer created for library methods and fields that are not callable (either statically or dynamically) or otherwise referred to from source code. This may affect third-party queries that use these nodes to identify library methods or fields that are present in DLL files where those methods or fields are unreferenced. If this presents a problem, consider using `Callable` and other non-dataflow classes to identify such library entities.
* C#: Add extractor support for attributes on indexers.
## 2.0.0
### Breaking Changes

View File

@@ -0,0 +1,15 @@
## 3.0.0
### Breaking Changes
* C#: Add support for MaD directly on properties and indexers using *attributes*. Using `Attribute.Getter` or `Attribute.Setter` in the model `ext` field applies the model to the getter or setter for properties and indexers. Prior to this change `Attribute` models unintentionally worked for property setters (if the property is decorated with the matching attribute). That is, a model that uses the `Attribute` feature directly on a property for a property setter needs to be changed to `Attribute.Setter`.
* C#: Remove all CIL tables and related QL library functionality.
### Deprecated APIs
* The class `ThreatModelFlowSource` has been renamed to `ActiveThreatModelSource` to more clearly reflect it only contains the currently active threat model sources. `ThreatModelFlowSource` has been marked as deprecated.
### Minor Analysis Improvements
* `DataFlow::Node` instances are no longer created for library methods and fields that are not callable (either statically or dynamically) or otherwise referred to from source code. This may affect third-party queries that use these nodes to identify library methods or fields that are present in DLL files where those methods or fields are unreferenced. If this presents a problem, consider using `Callable` and other non-dataflow classes to identify such library entities.
* C#: Add extractor support for attributes on indexers.

View File

@@ -1,5 +0,0 @@
/**
* The default QL library for modeling the Common Intermediate Language (CIL).
*/
import semmle.code.cil.CIL as CIL

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 2.0.0
lastReleaseVersion: 3.0.0

View File

@@ -1,5 +0,0 @@
/**
* The default QL library for modeling .NET definitions for both C# and CIL code.
*/
deprecated import semmle.code.dotnet.DotNet as DotNet

View File

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

View File

@@ -1,98 +0,0 @@
/**
* Provides classes for accesses.
*
* An access is any read or write of a variable.
*/
private import CIL
/** An instruction that accesses a variable. */
deprecated class Access extends Instruction, @cil_access {
/** Gets the declaration referenced by this instruction. */
Variable getTarget() { cil_access(this, result) }
}
/**
* An instruction that accesses a variable.
* This class is provided for consistency with the C# data model.
*/
deprecated class VariableAccess extends Access, @cil_access { }
/** An instruction that reads a variable. */
deprecated class ReadAccess extends VariableAccess, Expr, @cil_read_access {
override Type getType() { result = this.getTarget().getType() }
}
/** An instruction yielding an address. */
deprecated class ReadRef extends Expr, @cil_read_ref { }
/** An instruction that reads the address of a variable. */
deprecated class ReadRefAccess extends ReadAccess, ReadRef { }
/** An instruction that writes a variable. */
deprecated class WriteAccess extends VariableAccess, @cil_write_access {
/** Gets the expression whose value is used in this variable write. */
Expr getExpr() { none() }
}
/** An instruction that accesses a parameter. */
deprecated class ParameterAccess extends StackVariableAccess, @cil_arg_access {
override MethodParameter getTarget() { result = StackVariableAccess.super.getTarget() }
}
/** An instruction that reads a parameter. */
deprecated class ParameterReadAccess extends ParameterAccess, ReadAccess {
override int getPopCount() { result = 0 }
}
/** An instruction that writes to a parameter. */
deprecated class ParameterWriteAccess extends ParameterAccess, WriteAccess {
override int getPopCount() { result = 1 }
override Expr getExpr() { result = this.getOperand(0) }
}
/** An access to the `this` parameter. */
deprecated class ThisAccess extends ParameterReadAccess {
ThisAccess() { this.getTarget() instanceof ThisParameter }
}
/** An instruction that accesses a stack variable. */
deprecated class StackVariableAccess extends VariableAccess, @cil_stack_access {
override StackVariable getTarget() { result = VariableAccess.super.getTarget() }
}
/** An instruction that accesses a local variable. */
deprecated class LocalVariableAccess extends StackVariableAccess, @cil_local_access {
override LocalVariable getTarget() { result = StackVariableAccess.super.getTarget() }
}
/** An instruction that writes to a local variable. */
deprecated class LocalVariableWriteAccess extends LocalVariableAccess, WriteAccess {
override int getPopCount() { result = 1 }
override Expr getExpr() { result = this.getOperand(0) }
override string getExtra() { result = "L" + this.getTarget().getIndex() }
}
/** An instruction that reads a local variable. */
deprecated class LocalVariableReadAccess extends LocalVariableAccess, ReadAccess {
override int getPopCount() { result = 0 }
}
/** An instruction that accesses a field. */
deprecated class FieldAccess extends VariableAccess, @cil_field_access {
override Field getTarget() { result = VariableAccess.super.getTarget() }
override string getExtra() { result = this.getTarget().getName() }
/** Gets the qualifier of the access, if any. */
abstract Expr getQualifier();
}
/** An instruction that reads a field. */
abstract deprecated class FieldReadAccess extends FieldAccess, ReadAccess { }
/** An instruction that writes a field. */
abstract deprecated class FieldWriteAccess extends FieldAccess, WriteAccess { }

View File

@@ -1,45 +0,0 @@
/** Provides the `Attribute` class. */
private import CIL
private import semmle.code.csharp.Location as CS
/** An attribute to a declaration, such as a method, field, type or parameter. */
deprecated class Attribute extends Element, @cil_attribute {
/** Gets the declaration this attribute is attached to. */
Declaration getDeclaration() { cil_attribute(this, result, _) }
/** Gets the constructor used to construct this attribute. */
Method getConstructor() { cil_attribute(this, _, result) }
/** Gets the type of this attribute. */
Type getType() { result = this.getConstructor().getDeclaringType() }
override string toString() { result = "[" + this.getType().getName() + "(...)]" }
/** Gets the value of the `i`th argument of this attribute. */
string getArgument(int i) { cil_attribute_positional_argument(this, i, result) }
/** Gets the value of the named argument `name`. */
string getNamedArgument(string name) { cil_attribute_named_argument(this, name, result) }
/** Gets an argument of this attribute, if any. */
string getAnArgument() { result = this.getArgument(_) or result = this.getNamedArgument(_) }
override CS::Location getLocation() { result = this.getDeclaration().getLocation() }
}
/** A generic attribute to a declaration. */
deprecated class GenericAttribute extends Attribute {
private ConstructedType type;
GenericAttribute() { type = this.getType() }
/** Gets the total number of type arguments. */
int getNumberOfTypeArguments() { result = count(int i | cil_type_argument(type, i, _)) }
/** Gets the `i`th type argument, if any. */
Type getTypeArgument(int i) { result = type.getTypeArgument(i) }
/** Get a type argument. */
Type getATypeArgument() { result = this.getTypeArgument(_) }
}

View File

@@ -1,401 +0,0 @@
/**
* Provides classes representing basic blocks.
*/
private import CIL
/**
* A basic block, that is, a maximal straight-line sequence of control flow nodes
* without branches or joins.
*/
deprecated class BasicBlock extends Cached::TBasicBlockStart {
/** Gets an immediate successor of this basic block, if any. */
BasicBlock getASuccessor() { result.getFirstNode() = this.getLastNode().getASuccessor() }
/** Gets an immediate predecessor of this basic block, if any. */
BasicBlock getAPredecessor() { result.getASuccessor() = this }
/**
* Gets an immediate `true` successor, if any.
*
* An immediate `true` successor is a successor that is reached when
* the condition that ends this basic block evaluates to `true`.
*
* Example:
*
* ```csharp
* if (x < 0)
* x = -x;
* ```
*
* The basic block on line 2 is an immediate `true` successor of the
* basic block on line 1.
*/
BasicBlock getATrueSuccessor() { result.getFirstNode() = this.getLastNode().getTrueSuccessor() }
/**
* Gets an immediate `false` successor, if any.
*
* An immediate `false` successor is a successor that is reached when
* the condition that ends this basic block evaluates to `false`.
*
* Example:
*
* ```csharp
* if (!(x >= 0))
* x = -x;
* ```
*
* The basic block on line 2 is an immediate `false` successor of the
* basic block on line 1.
*/
BasicBlock getAFalseSuccessor() { result.getFirstNode() = this.getLastNode().getFalseSuccessor() }
/** Gets the control flow node at a specific (zero-indexed) position in this basic block. */
ControlFlowNode getNode(int pos) { Cached::bbIndex(this.getFirstNode(), result, pos) }
/** Gets a control flow node in this basic block. */
ControlFlowNode getANode() { result = this.getNode(_) }
/** Gets the first control flow node in this basic block. */
ControlFlowNode getFirstNode() { this = Cached::TBasicBlockStart(result) }
/** Gets the last control flow node in this basic block. */
ControlFlowNode getLastNode() { result = this.getNode(this.length() - 1) }
/** Gets the length of this basic block. */
int length() { result = strictcount(this.getANode()) }
/**
* Holds if this basic block strictly dominates basic block `bb`.
*
* That is, all paths reaching basic block `bb` from some entry point
* basic block must go through this basic block (which must be different
* from `bb`).
*
* Example:
*
* ```csharp
* int M(string s) {
* if (s == null)
* throw new ArgumentNullException(nameof(s));
* return s.Length;
* }
* ```
*
* The basic block starting on line 2 strictly dominates the
* basic block on line 4 (all paths from the entry point of `M`
* to `return s.Length;` must go through the null check).
*/
predicate strictlyDominates(BasicBlock bb) { bbIDominates+(this, bb) }
/**
* Holds if this basic block dominates basic block `bb`.
*
* That is, all paths reaching basic block `bb` from some entry point
* basic block must go through this basic block.
*
* Example:
*
* ```csharp
* int M(string s) {
* if (s == null)
* throw new ArgumentNullException(nameof(s));
* return s.Length;
* }
* ```
*
* The basic block starting on line 2 dominates the basic
* block on line 4 (all paths from the entry point of `M` to
* `return s.Length;` must go through the null check).
*
* This predicate is *reflexive*, so for example `if (s == null)` dominates
* itself.
*/
predicate dominates(BasicBlock bb) {
bb = this or
this.strictlyDominates(bb)
}
/**
* Holds if `df` is in the dominance frontier of this basic block.
* That is, this basic block dominates a predecessor of `df`, but
* does not dominate `df` itself.
*
* Example:
*
* ```csharp
* if (x < 0) {
* x = -x;
* if (x > 10)
* x--;
* }
* Console.Write(x);
* ```
*
* The basic block on line 6 is in the dominance frontier
* of the basic block starting on line 2 because that block
* dominates the basic block on line 4, which is a predecessor of
* `Console.Write(x);`. Also, the basic block starting on line 2
* does not dominate the basic block on line 6.
*/
predicate inDominanceFrontier(BasicBlock df) {
this.dominatesPredecessor(df) and
not this.strictlyDominates(df)
}
/**
* Holds if this basic block dominates a predecessor of `df`.
*/
private predicate dominatesPredecessor(BasicBlock df) { this.dominates(df.getAPredecessor()) }
/**
* Gets the basic block that immediately dominates this basic block, if any.
*
* That is, all paths reaching this basic block from some entry point
* basic block must go through the result, which is an immediate basic block
* predecessor of this basic block.
*
* Example:
*
* ```csharp
* int M(string s) {
* if (s == null)
* throw new ArgumentNullException(nameof(s));
* return s.Length;
* }
* ```
*
* The basic block starting on line 2 is an immediate dominator of
* the basic block online 4 (all paths from the entry point of `M`
* to `return s.Length;` must go through the null check, and the null check
* is an immediate predecessor of `return s.Length;`).
*/
BasicBlock getImmediateDominator() { bbIDominates(result, this) }
/**
* Holds if this basic block strictly post-dominates basic block `bb`.
*
* That is, all paths reaching an exit point basic block from basic
* block `bb` must go through this basic block (which must be different
* from `bb`).
*
* Example:
*
* ```csharp
* int M(string s) {
* try {
* return s.Length;
* }
* finally {
* Console.WriteLine("M");
* }
* }
* ```
*
* The basic block on line 6 strictly post-dominates the basic block on
* line 3 (all paths to the exit point of `M` from `return s.Length;`
* must go through the `WriteLine` call).
*/
predicate strictlyPostDominates(BasicBlock bb) { bbIPostDominates+(this, bb) }
/**
* Holds if this basic block post-dominates basic block `bb`.
*
* That is, all paths reaching an exit point basic block from basic
* block `bb` must go through this basic block.
*
* Example:
*
* ```csharp
* int M(string s) {
* try {
* return s.Length;
* }
* finally {
* Console.WriteLine("M");
* }
* }
* ```
*
* The basic block on line 6 post-dominates the basic block on line 3
* (all paths to the exit point of `M` from `return s.Length;` must go
* through the `WriteLine` call).
*
* This predicate is *reflexive*, so for example `Console.WriteLine("M");`
* post-dominates itself.
*/
predicate postDominates(BasicBlock bb) {
this.strictlyPostDominates(bb) or
this = bb
}
/**
* Holds if this basic block is in a loop in the control flow graph. This
* includes loops created by `goto` statements. This predicate may not hold
* even if this basic block is syntactically inside a `while` loop if the
* necessary back edges are unreachable.
*/
predicate inLoop() { this.getASuccessor+() = this }
/** Gets a textual representation of this basic block. */
string toString() { result = this.getFirstNode().toString() }
/** Gets the location of this basic block. */
Location getLocation() { result = this.getFirstNode().getLocation() }
}
/**
* Internal implementation details.
*/
cached
deprecated private module Cached {
/** Internal representation of basic blocks. */
cached
newtype TBasicBlock = TBasicBlockStart(ControlFlowNode cfn) { startsBB(cfn) }
/** Holds if `cfn` starts a new basic block. */
private predicate startsBB(ControlFlowNode cfn) {
not exists(cfn.getAPredecessor()) and exists(cfn.getASuccessor())
or
cfn.isJoin()
or
cfn.getAPredecessor().isBranch()
}
/**
* Holds if `succ` is a control flow successor of `pred` within
* the same basic block.
*/
private predicate intraBBSucc(ControlFlowNode pred, ControlFlowNode succ) {
succ = pred.getASuccessor() and
not startsBB(succ)
}
/**
* Holds if `cfn` is the `i`th node in basic block `bb`.
*
* In other words, `i` is the shortest distance from a node `bb`
* that starts a basic block to `cfn` along the `intraBBSucc` relation.
*/
cached
predicate bbIndex(ControlFlowNode bbStart, ControlFlowNode cfn, int i) =
shortestDistances(startsBB/1, intraBBSucc/2)(bbStart, cfn, i)
}
/**
* Holds if the first node of basic block `succ` is a control flow
* successor of the last node of basic block `pred`.
*/
deprecated private predicate succBB(BasicBlock pred, BasicBlock succ) {
succ = pred.getASuccessor()
}
/** Holds if `dom` is an immediate dominator of `bb`. */
deprecated predicate bbIDominates(BasicBlock dom, BasicBlock bb) =
idominance(entryBB/1, succBB/2)(_, dom, bb)
/** Holds if `pred` is a basic block predecessor of `succ`. */
deprecated private predicate predBB(BasicBlock succ, BasicBlock pred) { succBB(pred, succ) }
/** Holds if `dom` is an immediate post-dominator of `bb`. */
deprecated predicate bbIPostDominates(BasicBlock dom, BasicBlock bb) =
idominance(exitBB/1, predBB/2)(_, dom, bb)
/**
* An entry basic block, that is, a basic block whose first node is
* the entry node of a callable.
*/
deprecated class EntryBasicBlock extends BasicBlock {
EntryBasicBlock() { entryBB(this) }
}
/** Holds if `bb` is an entry basic block. */
deprecated private predicate entryBB(BasicBlock bb) {
bb.getFirstNode() instanceof MethodImplementation
}
/**
* An exit basic block, that is, a basic block whose last node is
* an exit node.
*/
deprecated class ExitBasicBlock extends BasicBlock {
ExitBasicBlock() { exitBB(this) }
}
/** Holds if `bb` is an exit basic block. */
deprecated private predicate exitBB(BasicBlock bb) { not exists(bb.getLastNode().getASuccessor()) }
/**
* A basic block with more than one predecessor.
*/
deprecated class JoinBlock extends BasicBlock {
JoinBlock() { this.getFirstNode().isJoin() }
}
/** A basic block that terminates in a condition, splitting the subsequent control flow. */
deprecated class ConditionBlock extends BasicBlock {
ConditionBlock() {
exists(BasicBlock succ |
succ = this.getATrueSuccessor()
or
succ = this.getAFalseSuccessor()
)
}
/**
* Holds if basic block `controlled` is controlled by this basic block with
* Boolean value `testIsTrue`. That is, `controlled` can only be reached from
* the callable entry point by going via the true edge (`testIsTrue = true`)
* or false edge (`testIsTrue = false`) out of this basic block.
*/
predicate controls(BasicBlock controlled, boolean testIsTrue) {
/*
* For this block to control the block `controlled` with `testIsTrue` the following must be true:
* Execution must have passed through the test i.e. `this` must strictly dominate `controlled`.
* Execution must have passed through the `testIsTrue` edge leaving `this`.
*
* Although "passed through the true edge" implies that `this.getATrueSuccessor()` dominates `controlled`,
* the reverse is not true, as flow may have passed through another edge to get to `this.getATrueSuccessor()`
* so we need to assert that `this.getATrueSuccessor()` dominates `controlled` *and* that
* all predecessors of `this.getATrueSuccessor()` are either `this` or dominated by `this.getATrueSuccessor()`.
*
* For example, in the following C# snippet:
* ```csharp
* if (x)
* controlled;
* false_successor;
* uncontrolled;
* ```
* `false_successor` dominates `uncontrolled`, but not all of its predecessors are `this` (`if (x)`)
* or dominated by itself. Whereas in the following code:
* ```csharp
* if (x)
* while (controlled)
* also_controlled;
* false_successor;
* uncontrolled;
* ```
* the block `while controlled` is controlled because all of its predecessors are `this` (`if (x)`)
* or (in the case of `also_controlled`) dominated by itself.
*
* The additional constraint on the predecessors of the test successor implies
* that `this` strictly dominates `controlled` so that isn't necessary to check
* directly.
*/
exists(BasicBlock succ |
this.isCandidateSuccessor(succ, testIsTrue) and
succ.dominates(controlled)
)
}
private predicate isCandidateSuccessor(BasicBlock succ, boolean testIsTrue) {
(
testIsTrue = true and succ = this.getATrueSuccessor()
or
testIsTrue = false and succ = this.getAFalseSuccessor()
) and
forall(BasicBlock pred | pred = succ.getAPredecessor() and pred != this | succ.dominates(pred))
}
}

View File

@@ -1,23 +0,0 @@
/** Provides the core CIL data model. */
import semmle.code.csharp.Location
import Element
import Instruction
import Instructions
import Access
import Variable
import Declaration
import Generics
import Type
import Types
import Method
import InstructionGroups
import BasicBlock
import Handler
import ControlFlow
import DataFlow
import Attribute
import Stubs
import CustomModifierReceiver
import Parameterizable
import semmle.code.cil.Ssa

View File

@@ -1,74 +0,0 @@
/**
* Provides predicates for analysing the return values of callables.
*/
private import CIL
cached
private module Cached {
/** Holds if method `m` always returns null. */
cached
deprecated predicate alwaysNullMethod(Method m) {
forex(Expr e | m.canReturn(e) | alwaysNullExpr(e))
}
/** Holds if method `m` always returns non-null. */
cached
deprecated predicate alwaysNotNullMethod(Method m) {
forex(Expr e | m.canReturn(e) | alwaysNotNullExpr(e))
}
/** Holds if method `m` always throws an exception. */
cached
deprecated predicate alwaysThrowsMethod(Method m) {
m.hasBody() and
not exists(m.getImplementation().getAnInstruction().(Return))
}
/** Holds if method `m` always throws an exception of type `t`. */
cached
deprecated predicate alwaysThrowsException(Method m, Type t) {
alwaysThrowsMethod(m) and
forex(Throw ex | ex = m.getImplementation().getAnInstruction() | t = ex.getExceptionType())
}
}
import Cached
pragma[noinline]
deprecated private predicate alwaysNullVariableUpdate(VariableUpdate vu) {
forex(Expr src | src = vu.getSource() | alwaysNullExpr(src))
}
/** Holds if expression `expr` always evaluates to `null`. */
deprecated private predicate alwaysNullExpr(Expr expr) {
expr instanceof NullLiteral
or
alwaysNullMethod(expr.(StaticCall).getTarget())
or
forex(Ssa::Definition def |
expr = any(Ssa::Definition def0 | def = def0.getAnUltimateDefinition()).getARead()
|
alwaysNullVariableUpdate(def.getVariableUpdate())
)
}
pragma[noinline]
deprecated private predicate alwaysNotNullVariableUpdate(VariableUpdate vu) {
forex(Expr src | src = vu.getSource() | alwaysNotNullExpr(src))
}
/** Holds if expression `expr` always evaluates to non-null. */
deprecated private predicate alwaysNotNullExpr(Expr expr) {
expr instanceof Opcodes::NewObj
or
expr instanceof Literal and not expr instanceof NullLiteral
or
alwaysNotNullMethod(expr.(StaticCall).getTarget())
or
forex(Ssa::Definition def |
expr = any(Ssa::Definition def0 | def = def0.getAnUltimateDefinition()).getARead()
|
alwaysNotNullVariableUpdate(def.getVariableUpdate())
)
}

View File

@@ -1,787 +0,0 @@
/**
* Provides checks for the consistency of the data model and database.
*/
private import CIL
private import csharp as CS
private import semmle.code.csharp.commons.QualifiedName
private newtype ConsistencyCheck =
MissingEntityCheck() or
deprecated TypeCheck(Type t) or
deprecated CfgCheck(ControlFlowNode n) or
deprecated DeclarationCheck(Declaration d) or
MissingCSharpCheck(CS::Declaration d)
/**
* A consistency violation in the database or data model.
*/
abstract deprecated class ConsistencyViolation extends ConsistencyCheck {
abstract string toString();
abstract string getMessage();
}
/**
* A check that is deliberately disabled.
*/
abstract deprecated class DisabledCheck extends ConsistencyViolation {
DisabledCheck() { none() }
}
/**
* A consistency violation on a control flow node.
*/
abstract deprecated class CfgViolation extends ConsistencyViolation, CfgCheck {
ControlFlowNode node;
CfgViolation() { this = CfgCheck(node) }
override string toString() { result = node.toString() }
}
/**
* A consistency violation in a specific instruction.
*/
abstract deprecated class InstructionViolation extends CfgViolation, CfgCheck {
Instruction instruction;
InstructionViolation() { this = CfgCheck(instruction) }
private string getInstructionsUpTo() {
result =
concat(Instruction i |
i.getIndex() <= instruction.getIndex() and
i.getImplementation() = instruction.getImplementation()
|
i.toString() + " [push: " + i.getPushCount() + ", pop: " + i.getPopCount() + "]", "; "
order by
i.getIndex()
)
}
override string toString() {
result =
instruction.getImplementation().getMethod().toStringWithTypes() + ": " +
instruction.toString() + ", " + this.getInstructionsUpTo()
}
}
/**
* A literal that does not have exactly one `getValue()`.
*/
deprecated class MissingValue extends InstructionViolation {
MissingValue() { exists(Literal l | l = instruction | count(l.getValue()) != 1) }
override string getMessage() { result = "Literal has invalid getValue()" }
}
/**
* A call that does not have exactly one `getTarget()`.
*/
deprecated class MissingCallTarget extends InstructionViolation {
MissingCallTarget() {
exists(Call c | c = instruction |
count(c.getTarget()) != 1 and not c instanceof Opcodes::Calli
or
count(c.(Opcodes::Calli).getTargetType()) != 1 and c instanceof Opcodes::Calli
)
}
override string getMessage() { result = "Call has invalid target" }
}
/**
* An instruction that has not been assigned a specific QL class.
*/
deprecated class MissingOpCode extends InstructionViolation {
MissingOpCode() { not exists(instruction.getOpcodeName()) }
override string getMessage() {
result = "Opcode " + instruction.getOpcode() + " is missing a QL class"
}
override string toString() {
result = "Unknown instruction in " + instruction.getImplementation().getMethod().toString()
}
}
/**
* An instruction that is missing an operand. It means that there is no instruction which pushes
* a value onto the stack for this instruction to pop.
*
* If this fails, it means that the `getPopCount`/`getPushCount`/control flow graph has failed.
* It could also mean that the target of a call has failed and has not determined the
* correct number of arguments.
*/
deprecated class MissingOperand extends InstructionViolation {
MissingOperand() {
exists(int op | op in [0 .. instruction.getPopCount() - 1] |
not exists(instruction.getOperand(op)) and not instruction instanceof DeadInstruction
)
}
int getMissingOperand() {
result in [0 .. instruction.getPopCount() - 1] and
not exists(instruction.getOperand(result))
}
override string getMessage() {
result = "This instruction is missing operand " + this.getMissingOperand()
}
}
/**
* A dead instruction, not reachable from any entry point.
* These should not exist, however it turns out that the Mono compiler sometimes
* emits them.
*/
deprecated class DeadInstruction extends Instruction {
DeadInstruction() { not exists(EntryPoint e | e.getASuccessor+() = this) }
}
/**
* An instruction that is not reachable from any entry point.
*
* If this fails, it means that the calculation of the call graph is incorrect.
* Disabled, because Mono compiler sometimes emits dead instructions.
*/
deprecated class DeadInstructionViolation extends InstructionViolation, DisabledCheck {
DeadInstructionViolation() { instruction instanceof DeadInstruction }
override string getMessage() { result = "This instruction is not reachable" }
}
deprecated class YesNoBranch extends ConditionalBranch {
YesNoBranch() { not this instanceof Opcodes::Switch }
}
/**
* A branch instruction that does not have exactly 2 successors.
*/
deprecated class InvalidBranchSuccessors extends InstructionViolation {
InvalidBranchSuccessors() {
// Mono compiler sometimes generates branches to the next instruction, which is just wrong.
// However it is valid CIL.
exists(YesNoBranch i | i = instruction | not count(i.getASuccessor()) in [1 .. 2])
}
override string getMessage() {
result = "Conditional branch has " + count(instruction.getASuccessor()) + " successors"
}
}
/**
* An instruction that has a true/false successor but is not a branch.
*/
deprecated class OnlyYesNoBranchHasTrueFalseSuccessors extends InstructionViolation {
OnlyYesNoBranchHasTrueFalseSuccessors() {
(exists(instruction.getTrueSuccessor()) or exists(instruction.getFalseSuccessor())) and
not instruction instanceof YesNoBranch
}
override string getMessage() { result = "This instruction has getTrue/FalseSuccessor()" }
}
/**
* An unconditional branch instruction that has more than one successor.
*/
deprecated class UnconditionalBranchSuccessors extends InstructionViolation {
UnconditionalBranchSuccessors() {
exists(UnconditionalBranch i | i = instruction | count(i.getASuccessor()) != 1)
}
override string getMessage() {
result = "Unconditional branch has " + count(instruction.getASuccessor()) + " successors"
}
}
/**
* A branch instruction that does not have a true successor.
*/
deprecated class NoTrueSuccessor extends InstructionViolation {
NoTrueSuccessor() { exists(YesNoBranch i | i = instruction | not exists(i.getTrueSuccessor())) }
override string getMessage() { result = "Missing a true successor" }
}
/**
* A branch instruction that does not have a false successor.
*/
deprecated class NoFalseSuccessor extends InstructionViolation {
NoFalseSuccessor() { exists(YesNoBranch i | i = instruction | not exists(i.getFalseSuccessor())) }
override string getMessage() { result = "Missing a false successor" }
}
/**
* An instruction whose true successor is not a successor.
*/
deprecated class TrueSuccessorIsSuccessor extends InstructionViolation {
TrueSuccessorIsSuccessor() {
exists(instruction.getTrueSuccessor()) and
not instruction.getTrueSuccessor() = instruction.getASuccessor()
}
override string getMessage() { result = "True successor isn't a successor" }
}
/**
* An instruction whose false successor is not a successor.
*/
deprecated class FalseSuccessorIsSuccessor extends InstructionViolation {
FalseSuccessorIsSuccessor() {
exists(instruction.getFalseSuccessor()) and
not instruction.getFalseSuccessor() = instruction.getASuccessor()
}
override string getMessage() { result = "True successor isn't a successor" }
}
/**
* An access that does not have exactly one target.
*/
deprecated class AccessMissingTarget extends InstructionViolation {
AccessMissingTarget() { exists(Access i | i = instruction | count(i.getTarget()) != 1) }
override string getMessage() { result = "Access has invalid getTarget()" }
}
/**
* A catch handler that doesn't have a caught exception type.
*/
deprecated class CatchHandlerMissingType extends CfgViolation {
CatchHandlerMissingType() { exists(CatchHandler h | h = node | not exists(h.getCaughtType())) }
override string getMessage() { result = "Catch handler missing caught type" }
}
/**
* A CFG node that does not have a stack size.
*/
deprecated class MissingStackSize extends CfgViolation {
MissingStackSize() {
(
not exists(node.getStackSizeAfter()) or
not exists(node.getStackSizeBefore())
) and
not node instanceof DeadInstruction
}
override string getMessage() { result = "Inconsistent stack size" }
}
/**
* A CFG node that does not have exactly one stack size.
* Disabled because inconsistent stack sizes have been observed.
*/
deprecated class InvalidStackSize extends CfgViolation, DisabledCheck {
InvalidStackSize() {
(
count(node.getStackSizeAfter()) != 1 or
count(node.getStackSizeBefore()) != 1
) and
not node instanceof DeadInstruction
}
override string getMessage() {
result =
"Inconsistent stack sizes " + count(node.getStackSizeBefore()) + " before and " +
count(node.getStackSizeAfter()) + " after"
}
}
/**
* A CFG node that does not have exactly 1 `getPopCount()`.
*/
deprecated class InconsistentPopCount extends CfgViolation {
InconsistentPopCount() { count(node.getPopCount()) != 1 }
override string getMessage() {
result = "Cfg node has " + count(node.getPopCount()) + " pop counts"
}
}
/**
* A CFG node that does not have exactly one `getPushCount()`.
*/
deprecated class InconsistentPushCount extends CfgViolation {
InconsistentPushCount() { count(node.getPushCount()) != 1 }
override string getMessage() {
result = "Cfg node has " + count(node.getPushCount()) + " push counts"
}
}
/**
* A return instruction that does not have a stack size of 0 after it.
*/
deprecated class InvalidReturn extends InstructionViolation {
InvalidReturn() { instruction instanceof Return and instruction.getStackSizeAfter() != 0 }
override string getMessage() { result = "Return has invalid stack size" }
}
/**
* A throw instruction that does not have a stack size of 0 after it.
*/
deprecated class InvalidThrow extends InstructionViolation, DisabledCheck {
InvalidThrow() { instruction instanceof Throw and instruction.getStackSizeAfter() != 0 }
override string getMessage() {
result = "Throw has invalid stack size: " + instruction.getStackSizeAfter()
}
}
/**
* A field access where the field is "static" but the instruction is "instance".
*/
deprecated class StaticFieldTarget extends InstructionViolation {
StaticFieldTarget() {
exists(FieldAccess i | i = instruction |
(i instanceof Opcodes::Stfld or i instanceof Opcodes::Stfld) and
i.getTarget().isStatic()
)
}
override string getMessage() { result = "Inconsistent static field" }
}
/**
* A branch without a target.
*/
deprecated class BranchWithoutTarget extends InstructionViolation {
BranchWithoutTarget() {
instruction = any(Branch b | not exists(b.getTarget()) and not b instanceof Opcodes::Switch)
}
override string getMessage() { result = "Branch without target" }
}
/**
* A consistency violation in a type.
*/
deprecated class TypeViolation extends ConsistencyViolation, TypeCheck {
/** Gets the type containing the violation. */
Type getType() { this = TypeCheck(result) }
override string toString() { result = this.getType().toString() }
abstract override string getMessage();
}
/**
* A type that has both type arguments and type parameters.
*/
deprecated class TypeIsBothConstructedAndUnbound extends TypeViolation {
TypeIsBothConstructedAndUnbound() {
this.getType() instanceof ConstructedGeneric and this.getType() instanceof UnboundGeneric
}
override string getMessage() { result = "Type is both constructed and unbound" }
}
/**
* The location of a constructed generic type should be the same
* as the location of its unbound generic type.
*/
deprecated class InconsistentTypeLocation extends TypeViolation {
InconsistentTypeLocation() {
this.getType().getLocation() != this.getType().getUnboundDeclaration().getLocation()
}
override string getMessage() { result = "Inconsistent constructed type location" }
}
/**
* A constructed type that does not match its unbound generic type.
*/
deprecated class TypeParameterMismatch extends TypeViolation {
TypeParameterMismatch() {
this.getType().(ConstructedGeneric).getNumberOfTypeArguments() !=
this.getType().getUnboundType().(UnboundGeneric).getNumberOfTypeParameters()
}
override string getMessage() {
result =
"Constructed type (" + this.getType().toStringWithTypes() + ") has " +
this.getType().(ConstructedGeneric).getNumberOfTypeArguments() +
" type arguments and unbound type (" + this.getType().getUnboundType().toStringWithTypes() +
") has " + this.getType().getUnboundType().(UnboundGeneric).getNumberOfTypeParameters() +
" type parameters"
}
}
/**
* A consistency violation in a method.
*/
deprecated class MethodViolation extends ConsistencyViolation, DeclarationCheck {
/** Gets the method containing the violation. */
Method getMethod() { this = DeclarationCheck(result) }
override string toString() { result = this.getMethod().toString() }
override string getMessage() { none() }
}
/**
* The location of a constructed method should be equal to the
* location of its unbound generic.
*/
deprecated class InconsistentMethodLocation extends MethodViolation {
InconsistentMethodLocation() {
this.getMethod().getLocation() != this.getMethod().getUnboundDeclaration().getLocation()
}
override string getMessage() { result = "Inconsistent constructed method location" }
}
/**
* A constructed method that does not match its unbound method.
*/
deprecated class ConstructedMethodTypeParams extends MethodViolation {
ConstructedMethodTypeParams() {
this.getMethod().(ConstructedGeneric).getNumberOfTypeArguments() !=
this.getMethod().getUnboundDeclaration().(UnboundGeneric).getNumberOfTypeParameters()
}
override string getMessage() {
result =
"The constructed method " + this.getMethod().toStringWithTypes() +
" does not match unbound method " +
this.getMethod().getUnboundDeclaration().toStringWithTypes()
}
}
/**
* A violation marking an entity that should be present but is not.
*/
abstract deprecated class MissingEntityViolation extends ConsistencyViolation, MissingEntityCheck {
override string toString() { result = "Missing entity" }
}
/**
* The type `object` is missing from the database.
*/
deprecated class MissingObjectViolation extends MissingEntityViolation {
MissingObjectViolation() {
exists(this) and
not exists(ObjectType o)
}
override string getMessage() { result = "Object missing" }
}
/**
* An override that is invalid because the overridden method is not in a base class.
*/
deprecated class InvalidOverride extends MethodViolation {
private Method base;
InvalidOverride() {
base = this.getMethod().getOverriddenMethod() and
not this.getMethod().getDeclaringType().getABaseType+() = base.getDeclaringType() and
base.getDeclaringType().isUnboundDeclaration() // Bases classes of constructed types aren't extracted properly.
}
override string getMessage() {
exists(string qualifier, string type |
base.getDeclaringType().hasFullyQualifiedName(qualifier, type)
|
result =
"Overridden method from " + getQualifiedName(qualifier, type) + " is not in a base type"
)
}
}
/**
* A pointer type that does not have a pointee type.
*/
deprecated class InvalidPointerType extends TypeViolation {
InvalidPointerType() {
exists(PointerType p | p = this.getType() | count(p.getReferentType()) != 1)
}
override string getMessage() { result = "Invalid Pointertype.getPointeeType()" }
}
/**
* An array with an invalid `getElementType`.
*/
deprecated class ArrayTypeMissingElement extends TypeViolation {
ArrayTypeMissingElement() {
exists(ArrayType t | t = this.getType() | count(t.getElementType()) != 1)
}
override string getMessage() { result = "Invalid ArrayType.getElementType()" }
}
/**
* An array with an invalid `getRank`.
*/
deprecated class ArrayTypeInvalidRank extends TypeViolation {
ArrayTypeInvalidRank() { exists(ArrayType t | t = this.getType() | not t.getRank() > 0) }
override string getMessage() { result = "Invalid ArrayType.getRank()" }
}
/**
* A type should have at most one kind, except for missing referenced types
* where the interface/class is unknown.
*/
deprecated class KindViolation extends TypeViolation {
KindViolation() {
count(typeKind(this.getType())) != 1 and
exists(this.getType().getLocation())
}
override string getMessage() {
result = "Invalid kinds on type: " + concat(typeKind(this.getType()), " ")
}
}
/**
* The type of a kind must be consistent between a constructed generic and its
* unbound generic.
*/
deprecated class InconsistentKind extends TypeViolation {
InconsistentKind() {
typeKind(this.getType()) != typeKind(this.getType().getUnboundDeclaration())
}
override string getMessage() { result = "Inconsistent type kind of source declaration" }
}
deprecated private string typeKind(Type t) {
t instanceof Interface and result = "interface"
or
t instanceof Class and result = "class"
or
t instanceof TypeParameter and result = "type parameter"
or
t instanceof ArrayType and result = "array"
or
t instanceof PointerType and result = "pointer"
}
/**
* A violation in a `Member`.
*/
abstract deprecated class DeclarationViolation extends ConsistencyViolation, DeclarationCheck {
abstract override string getMessage();
/** Gets the member containing the potential violation. */
Declaration getDeclaration() { this = DeclarationCheck(result) }
override string toString() { result = this.getDeclaration().toString() }
}
/**
* Properties that have no accessors.
*/
deprecated class PropertyWithNoAccessors extends DeclarationViolation {
PropertyWithNoAccessors() {
exists(Property p | p = this.getDeclaration() | not exists(p.getAnAccessor()))
}
override string getMessage() { result = "Property has no accessors" }
}
/**
* An expression that have an unexpected push count.
*/
deprecated class ExprPushCount extends InstructionViolation {
ExprPushCount() {
instruction instanceof Expr and
not instruction instanceof Opcodes::Dup and
if instruction instanceof Call
then not instruction.getPushCount() in [0 .. 1]
else instruction.(Expr).getPushCount() != 1
}
override string getMessage() {
result = "Instruction has unexpected push count " + instruction.getPushCount()
}
}
/**
* An expression that does not have exactly one type.
* Note that calls with no return have type `System.Void`.
*/
deprecated class ExprMissingType extends InstructionViolation {
ExprMissingType() {
// Don't have types for the following op codes:
not instruction instanceof Opcodes::Ldftn and
not instruction instanceof Opcodes::Localloc and
not instruction instanceof Opcodes::Ldvirtftn and
not instruction instanceof Opcodes::Arglist and
not instruction instanceof Opcodes::Refanytype and
instruction.getPushCount() >= 1 and
count(instruction.getType()) != 1 and
// OS specific (osx) specific inconsistency
not instruction
.getImplementation()
.getMethod()
.hasFullyQualifiedName("System.Runtime.InteropServices.RuntimeInformation",
"get_OSDescription")
}
override string getMessage() { result = "Expression is missing getType()" }
}
/**
* An instruction that has a push count of 0, yet is still used as an operand
*/
deprecated class InvalidExpressionViolation extends InstructionViolation {
InvalidExpressionViolation() {
instruction.getPushCount() = 0 and
exists(Instruction expr | instruction = expr.getAnOperand())
}
override string getMessage() {
result = "This instruction is used as an operand but pushes no values"
}
}
/**
* A type that has multiple entities with the same qualified name in `System`.
* .NET Core does sometimes duplicate types, so this check is disabled.
*/
deprecated class TypeMultiplyDefined extends TypeViolation, DisabledCheck {
TypeMultiplyDefined() {
this.getType().getParent().getName() = "System" and
not this.getType() instanceof ConstructedGeneric and
not this.getType() instanceof ArrayType and
this.getType().isPublic() and
count(Type t |
not t instanceof ConstructedGeneric and
t.toStringWithTypes() = this.getType().toStringWithTypes()
) != 1
}
override string getMessage() {
result =
"This type (" + this.getType().toStringWithTypes() + ") has " +
count(Type t |
not t instanceof ConstructedGeneric and
t.toStringWithTypes() = this.getType().toStringWithTypes()
) + " entities"
}
}
/**
* A C# declaration which is expected to have a corresponding CIL declaration, but for some reason does not.
*/
deprecated class MissingCilDeclaration extends ConsistencyViolation, MissingCSharpCheck {
MissingCilDeclaration() {
exists(CS::Declaration decl | this = MissingCSharpCheck(decl) |
expectedCilDeclaration(decl) and
not exists(Declaration d | decl = d.getCSharpDeclaration())
)
}
CS::Declaration getDeclaration() { this = MissingCSharpCheck(result) }
override string getMessage() {
result =
"Cannot locate CIL for " + this.getDeclaration().toStringWithTypes() + " of class " +
this.getDeclaration().getPrimaryQlClasses()
}
override string toString() { result = this.getDeclaration().toStringWithTypes() }
}
/**
* Holds if the C# declaration is expected to have a CIl declaration.
*/
deprecated private predicate expectedCilDeclaration(CS::Declaration decl) {
decl = decl.getUnboundDeclaration() and
not decl instanceof CS::ArrayType and
decl.getALocation() instanceof CS::Assembly and
not decl.(CS::Modifiable).isInternal() and
not decl.(CS::Constructor).getNumberOfParameters() = 0 and // These are sometimes implicit
not decl.(CS::Method).getReturnType() instanceof CS::UnknownType and
not exists(CS::Parameter p | p = decl.(CS::Parameterizable).getAParameter() |
not expectedCilDeclaration(p)
) and
not decl instanceof CS::AnonymousClass and
(decl instanceof CS::Parameter implies expectedCilDeclaration(decl.(CS::Parameter).getType())) and
(decl instanceof CS::Parameter implies expectedCilDeclaration(decl.getParent())) and
(decl instanceof CS::Member implies expectedCilDeclaration(decl.getParent())) and
(
decl instanceof CS::Field
or
decl instanceof CS::Property
or
decl instanceof CS::ValueOrRefType
or
decl instanceof CS::Event
or
decl instanceof CS::Constructor
or
decl instanceof CS::Destructor
or
decl instanceof CS::Operator
or
decl instanceof CS::Method
or
decl instanceof CS::Parameter
)
}
/** A member with an invalid name. */
deprecated class MemberWithInvalidName extends DeclarationViolation {
MemberWithInvalidName() {
exists(string name | name = this.getDeclaration().(Member).getName() |
exists(name.indexOf(".")) and
not name = ".ctor" and
not name = ".cctor"
)
}
override string getMessage() {
result = "Invalid name " + this.getDeclaration().(Member).getName()
}
}
deprecated class ConstructedSourceDeclarationMethod extends MethodViolation {
Method method;
ConstructedSourceDeclarationMethod() {
method = this.getMethod() and
method = method.getUnboundDeclaration() and
(
method instanceof ConstructedGeneric or
method.getDeclaringType() instanceof ConstructedGeneric
)
}
override string getMessage() {
result = "Source declaration " + method.toStringWithTypes() + " is constructed"
}
}
/** A declaration with multiple labels. */
deprecated class DeclarationWithMultipleLabels extends DeclarationViolation {
DeclarationWithMultipleLabels() {
exists(Declaration d | this = DeclarationCheck(d) | strictcount(d.getLabel()) > 1)
}
override string getMessage() {
result = "Multiple labels " + concat(this.getDeclaration().getLabel(), ", ")
}
}
/** A declaration without a label. */
deprecated class DeclarationWithoutLabel extends DeclarationViolation {
DeclarationWithoutLabel() {
exists(Declaration d | this = DeclarationCheck(d) |
d.isUnboundDeclaration() and
not d instanceof TypeParameter and
not exists(d.getLabel()) and
(d instanceof Callable or d instanceof Type)
)
}
override string getMessage() { result = "No label" }
}

View File

@@ -1,179 +0,0 @@
/**
* Provides classes for control flow.
*/
private import CIL
/** A node in the control flow graph. */
deprecated class ControlFlowNode extends @cil_controlflow_node {
/** Gets a textual representation of this control flow node. */
string toString() { none() }
/** Gets the location of this control flow node. */
Location getLocation() { none() }
/**
* Gets the number of items this node pushes onto the stack.
* This value is either 0 or 1, except for the instruction `dup`
* which pushes 2 values onto the stack.
*/
int getPushCount() { result = 0 }
/** Gets the number of items this node pops from the stack. */
int getPopCount() { result = 0 }
/** Gets a successor of this node, if any. */
final Instruction getASuccessor() { result = this.getASuccessorType(_) }
/** Gets a true successor of this node, if any. */
final Instruction getTrueSuccessor() { result = this.getASuccessorType(any(TrueFlow f)) }
/** Gets a false successor of this node, if any. */
final Instruction getFalseSuccessor() { result = this.getASuccessorType(any(FalseFlow f)) }
/** Gets a successor to this node, of type `type`, if any. */
cached
Instruction getASuccessorType(FlowType t) { none() }
/** Gets a predecessor of this node, if any. */
ControlFlowNode getAPredecessor() { result.getASuccessor() = this }
/**
* Gets an instruction that supplies the `i`th operand to this instruction.
* Note that this can be multi-valued.
*/
cached
ControlFlowNode getOperand(int i) {
// Immediate predecessor pushes the operand
i in [0 .. this.getPopCount() - 1] and
result = this.getAPredecessor() and
i < result.getPushCount()
or
// Transitive predecessor pushes the operand
exists(ControlFlowNode mid, int pushes | this.getOperandRec(mid, i, pushes) |
pushes - mid.getStackDelta() < result.getPushCount() and
result = mid.getAPredecessor()
)
}
/**
* Gets the type of the `i`th operand. Unlike `getOperand(i).getType()`, this
* predicate takes into account when there are multiple possible operands with
* different types.
*/
Type getOperandType(int i) {
strictcount(this.getOperand(i)) = 1 and
result = this.getOperand(i).getType()
or
strictcount(this.getOperand(i)) = 2 and
exists(ControlFlowNode op1, ControlFlowNode op2, Type t2 |
op1 = this.getOperand(i) and
op2 = this.getOperand(i) and
op1 != op2 and
result = op1.getType() and
t2 = op2.getType()
|
result = t2
or
result.(PrimitiveType).getUnderlyingType().getConversionIndex() >
t2.(PrimitiveType).getUnderlyingType().getConversionIndex()
or
op2 instanceof NullLiteral
)
}
/** Gets an operand of this instruction, if any. */
ControlFlowNode getAnOperand() { result = this.getOperand(_) }
/** Gets an expression that consumes the output of this instruction on the stack. */
Instruction getParentExpr() { this = result.getAnOperand() }
/**
* Holds if `pred` is a transitive predecessor of this instruction, this
* instruction pops operand `i`, `pushes` additional pushes are required
* for operand `i` at node `pred`, and no instruction between (and including)
* `pred` and this instruction is a push for operand `i`.
*/
private predicate getOperandRec(ControlFlowNode pred, int i, int pushes) {
// Invariant: no node is a push for operand `i`
pushes >= pred.getPushCount() and
(
i in [0 .. this.getPopCount() - 1] and
pred = this.getAPredecessor() and
pushes = i
or
exists(ControlFlowNode mid, int pushes0 | this.getOperandRec(mid, i, pushes0) |
pushes = pushes0 - mid.getStackDelta() and
// This is a guard to prevent ill formed programs
// and other logic errors going into an infinite loop.
pushes <= this.getImplementation().getStackSize() and
pred = mid.getAPredecessor()
)
)
}
private int getStackDelta() { result = this.getPushCount() - this.getPopCount() }
/** Gets the stack size before this instruction. */
int getStackSizeBefore() { result = this.getAPredecessor().getStackSizeAfter() }
/** Gets the stack size after this instruction. */
final int getStackSizeAfter() {
// This is a guard to prevent ill formed programs
// and other logic errors going into an infinite loop.
result in [0 .. this.getImplementation().getStackSize()] and
result = this.getStackSizeBefore() + this.getStackDelta()
}
/** Gets the method containing this control flow node. */
MethodImplementation getImplementation() { none() }
/**
* Gets the type of the item pushed onto the stack, if any.
*
* If called via `ControlFlowNode::getOperand(i).getType()`, consider using
* `ControlFlowNode::getOperandType(i)` instead.
*/
cached
Type getType() { none() }
/** Holds if this control flow node has more than one predecessor. */
predicate isJoin() { strictcount(this.getAPredecessor()) > 1 }
/** Holds if this control flow node has more than one successor. */
predicate isBranch() { strictcount(this.getASuccessor()) > 1 }
}
/**
* A control flow entry point. Either a method (`MethodImplementation`) or a handler (`Handler`).
*
* Handlers are control flow nodes because they push the handled exception onto the stack.
*/
deprecated class EntryPoint extends ControlFlowNode, @cil_entry_point {
override int getStackSizeBefore() { result = 0 }
}
deprecated private newtype TFlowType =
TNormalFlow() or
TTrueFlow() or
TFalseFlow()
/** A type of control flow. Either normal flow (`NormalFlow`), true flow (`TrueFlow`) or false flow (`FalseFlow`). */
abstract deprecated class FlowType extends TFlowType {
abstract string toString();
}
/** Normal control flow. */
deprecated class NormalFlow extends FlowType, TNormalFlow {
override string toString() { result = "" }
}
/** True control flow. */
deprecated class TrueFlow extends FlowType, TTrueFlow {
override string toString() { result = "true" }
}
/** False control flow. */
deprecated class FalseFlow extends FlowType, TFalseFlow {
override string toString() { result = "false" }
}

View File

@@ -1,21 +0,0 @@
/**
* Provides a class to represent `modopt` and `modreq` declarations.
*/
private import CIL
private import dotnet
/**
* A class to represent entities that can receive custom modifiers. Custom modifiers can be attached to
* - the type of a `Field`,
* - the return type of a `Method` or `Property`,
* - the type of parameters.
* A `CustomModifierReceiver` is therefore either a `Field`, `Property`, `Method`, or `Parameter`.
*/
deprecated class CustomModifierReceiver extends Declaration, @cil_custom_modifier_receiver {
/** Holds if this targeted type has `modifier` applied as `modreq`. */
predicate hasRequiredCustomModifier(Type modifier) { cil_custom_modifiers(this, modifier, 1) }
/** Holds if this targeted type has `modifier` applied as `modopt`. */
predicate hasOptionalCustomModifier(Type modifier) { cil_custom_modifiers(this, modifier, 0) }
}

View File

@@ -1,69 +0,0 @@
/**
* Provides a collection of building blocks and utilities for data flow.
*/
private import CIL
/**
* A node in the data flow graph.
*
* Either an instruction (`Instruction`), a method return (`Method`), or a variable (`Variable`).
*/
deprecated class DataFlowNode extends @cil_dataflow_node {
/** Gets a textual representation of this data flow node. */
abstract string toString();
/** Gets the type of this data flow node. */
Type getType() { none() }
/** Gets the method that contains this dataflow node. */
Method getMethod() { none() }
/** Gets the location of this dataflow node. */
Location getLocation() { none() }
}
/** A node that updates a variable. */
abstract deprecated class VariableUpdate extends DataFlowNode {
/** Gets the value assigned, if any. */
abstract DataFlowNode getSource();
/** Gets the variable that is updated. */
abstract Variable getVariable();
/** Holds if this variable update happens at index `i` in basic block `bb`. */
abstract predicate updatesAt(BasicBlock bb, int i);
}
deprecated private class MethodParameterDef extends VariableUpdate, MethodParameter {
override MethodParameter getSource() { result = this }
override MethodParameter getVariable() { result = this }
override predicate updatesAt(BasicBlock bb, int i) {
bb.(EntryBasicBlock).getANode().getImplementation().getMethod() = this.getMethod() and
i = -1
}
}
deprecated private class VariableWrite extends VariableUpdate, WriteAccess {
override Expr getSource() { result = this.getExpr() }
override Variable getVariable() { result = this.getTarget() }
override predicate updatesAt(BasicBlock bb, int i) { this = bb.getNode(i) }
}
deprecated private class MethodOutOrRefTarget extends VariableUpdate, Call {
int parameterIndex;
MethodOutOrRefTarget() { this.getTarget().getRawParameter(parameterIndex).hasOutFlag() }
override Variable getVariable() {
result = this.getRawArgument(parameterIndex).(ReadAccess).getTarget()
}
override Expr getSource() { none() }
override predicate updatesAt(BasicBlock bb, int i) { this = bb.getNode(i) }
}

View File

@@ -1,148 +0,0 @@
/**
* Provides classes for declarations and members.
*/
import CIL
private import dotnet
private import semmle.code.csharp.Member as CS
private import semmle.code.csharp.commons.QualifiedName
/**
* A declaration. Either a member (`Member`) or a variable (`Variable`).
*/
deprecated class Declaration extends DotNet::Declaration, Element, @cil_declaration {
/** Gets an attribute (for example `[Obsolete]`) of this declaration, if any. */
Attribute getAnAttribute() { result.getDeclaration() = this }
/**
* Gets the C# declaration corresponding to this CIL declaration, if any.
* Note that this is only for source/unconstructed declarations.
*/
CS::Declaration getCSharpDeclaration() {
result = toCSharpNonTypeParameter(this) or
result = toCSharpTypeParameter(this)
}
override Declaration getUnboundDeclaration() { result = this }
deprecated override predicate hasQualifiedName(string qualifier, string name) {
exists(string dqualifier, string dname |
this.getDeclaringType().hasQualifiedName(dqualifier, dname) and
qualifier = getQualifiedName(dqualifier, dname)
) and
name = this.getName()
}
override predicate hasFullyQualifiedName(string qualifier, string name) {
exists(string dqualifier, string dname |
this.getDeclaringType().hasFullyQualifiedName(dqualifier, dname) and
qualifier = getQualifiedName(dqualifier, dname)
) and
name = this.getName()
}
}
deprecated private CS::Declaration toCSharpNonTypeParameter(Declaration d) {
result.(DotNet::Declaration).matchesHandle(d)
}
deprecated private CS::TypeParameter toCSharpTypeParameter(TypeParameter tp) {
toCSharpTypeParameterJoin(tp, result.getIndex(), result.getGeneric())
}
pragma[nomagic]
deprecated private predicate toCSharpTypeParameterJoin(
TypeParameter tp, int i, CS::UnboundGeneric ug
) {
exists(TypeContainer tc |
tp.getIndex() = i and
tc = tp.getGeneric() and
ug = toCSharpNonTypeParameter(tc)
)
}
/**
* A member of a type. Either a type (`Type`), a method (`Method`), a property (`Property`), or an event (`Event`).
*/
deprecated class Member extends DotNet::Member, Declaration, @cil_member {
override predicate isPublic() { cil_public(this) }
override predicate isProtected() { cil_protected(this) }
override predicate isPrivate() { cil_private(this) }
override predicate isInternal() { cil_internal(this) }
override predicate isSealed() { cil_sealed(this) }
override predicate isAbstract() { cil_abstract(this) }
override predicate isStatic() { cil_static(this) }
/** Holds if this member has a security attribute. */
predicate hasSecurity() { cil_security(this) }
override Location getLocation() { result = this.getDeclaringType().getLocation() }
}
/** A property. */
deprecated class Property extends DotNet::Property, Member, CustomModifierReceiver, @cil_property {
override string getName() { cil_property(this, _, result, _) }
/** Gets the type of this property. */
override Type getType() { cil_property(this, _, _, result) }
override ValueOrRefType getDeclaringType() { cil_property(this, result, _, _) }
/** Gets the getter of this property, if any. */
override Getter getGetter() { this = result.getProperty() }
/** Gets the setter of this property, if any. */
override Setter getSetter() { this = result.getProperty() }
/** Gets an accessor of this property. */
Accessor getAnAccessor() { result = this.getGetter() or result = this.getSetter() }
override string toString() { result = "property " + this.getName() }
override string toStringWithTypes() {
result =
this.getType().toStringWithTypes() + " " + this.getDeclaringType().toStringWithTypes() + "." +
this.getName()
}
}
/** A property that is trivial (wraps a field). */
deprecated class TrivialProperty extends Property {
TrivialProperty() {
this.getGetter().(TrivialGetter).getField() = this.getSetter().(TrivialSetter).getField()
}
/** Gets the underlying field of this property. */
Field getField() { result = this.getGetter().(TrivialGetter).getField() }
}
/** An event. */
deprecated class Event extends DotNet::Event, Member, @cil_event {
override string getName() { cil_event(this, _, result, _) }
/** Gets the type of this event. */
Type getType() { cil_event(this, _, _, result) }
override ValueOrRefType getDeclaringType() { cil_event(this, result, _, _) }
/** Gets the add event accessor. */
Method getAddEventAccessor() { cil_adder(this, result) }
/** Gets the remove event accessor. */
Method getRemoveEventAccessor() { cil_remover(this, result) }
/** Gets the raiser. */
Method getRaiser() { cil_raiser(this, result) }
override string toString() { result = "event " + this.getName() }
override string toStringWithTypes() {
result = this.getDeclaringType().toStringWithTypes() + "." + this.getName()
}
}

View File

@@ -1,15 +0,0 @@
/** Provides the `Element` class, the base class of all CIL program elements. */
private import dotnet
import semmle.code.csharp.Location
/** An element. */
deprecated class Element extends DotNet::Element, @cil_element {
override Location getLocation() { result = bestLocation(this) }
}
cached
deprecated private Location bestLocation(Element e) {
result = e.getALocation() and
(e.getALocation().getFile().isPdbSourceFile() implies result.getFile().isPdbSourceFile())
}

View File

@@ -1,59 +0,0 @@
/** Provides classes for generic types and methods. */
private import CIL
private import dotnet
/**
* A generic declaration. Either an unbound generic (`UnboundGeneric`) or a
* constructed generic (`ConstructedGeneric`).
*/
deprecated class Generic extends DotNet::Generic, Declaration, TypeContainer {
Generic() {
cil_type_parameter(this, _, _) or
cil_type_argument(this, _, _)
}
}
/** An unbound generic type or method. */
deprecated class UnboundGeneric extends Generic, DotNet::UnboundGeneric {
UnboundGeneric() { cil_type_parameter(this, _, _) }
final override TypeParameter getTypeParameter(int n) { cil_type_parameter(this, n, result) }
}
/** A constructed generic type or method. */
deprecated class ConstructedGeneric extends Generic, DotNet::ConstructedGeneric {
ConstructedGeneric() { cil_type_argument(this, _, _) }
final override Type getTypeArgument(int n) { cil_type_argument(this, n, result) }
}
/** Gets the concatenation of the `getName()` of type arguments. */
language[monotonicAggregates]
deprecated private string getTypeArgumentsNames(ConstructedGeneric cg) {
result = strictconcat(Type t, int i | t = cg.getTypeArgument(i) | t.getName(), "," order by i)
}
/** An unbound generic type. */
deprecated class UnboundGenericType extends UnboundGeneric, Type { }
/** An unbound generic method. */
deprecated class UnboundGenericMethod extends UnboundGeneric, Method { }
/** A constructed generic type. */
deprecated class ConstructedType extends ConstructedGeneric, Type {
final override UnboundGenericType getUnboundGeneric() { result = this.getUnboundType() }
override predicate isInterface() { this.getUnboundType().isInterface() }
override predicate isClass() { this.getUnboundType().isClass() }
final override string getName() {
result = this.getUndecoratedName() + "<" + getTypeArgumentsNames(this) + ">"
}
}
/** A constructed generic method. */
deprecated class ConstructedMethod extends ConstructedGeneric, Method {
final override UnboundGenericMethod getUnboundGeneric() { result = this.getUnboundMethod() }
}

View File

@@ -1,83 +0,0 @@
/**
* Provides classes for different types of handler.
*/
private import CIL
/**
* A handler is a piece of code that can be executed out of sequence, for example
* when an instruction generates an exception or leaves a `finally` block.
*
* Each handler has a scope representing the block of instructions guarded by
* this handler (corresponding to a C# `try { ... }` block), and a block of instructions
* to execute when the handler is triggered (corresponding to a `catch` or `finally` block).
*
* Handlers are entry points (`EntryPoint`) so that they can
* provide values on the stack, for example the value of the current exception. This is why
* some handlers have a push count of 1.
*
* Either a finally handler (`FinallyHandler`), filter handler (`FilterHandler`),
* catch handler (`CatchHandler`), or a fault handler (`FaultHandler`).
*/
deprecated class Handler extends Element, EntryPoint, @cil_handler {
override MethodImplementation getImplementation() { cil_handler(this, result, _, _, _, _, _) }
/** Gets the 0-based index of this handler. Handlers are evaluated in this sequence. */
int getIndex() { cil_handler(this, _, result, _, _, _, _) }
/** Gets the first instruction in the `try` block of this handler. */
Instruction getTryStart() { cil_handler(this, _, _, _, result, _, _) }
/** Gets the last instruction in the `try` block of this handler. */
Instruction getTryEnd() { cil_handler(this, _, _, _, _, result, _) }
/** Gets the first instruction in the `catch`/`finally` block. */
Instruction getHandlerStart() { cil_handler(this, _, _, _, _, _, result) }
/**
* Holds if the instruction `i` is in the scope of this handler.
*/
predicate isInScope(Instruction i) {
i.getImplementation() = this.getImplementation() and
i.getIndex() in [this.getTryStart().getIndex() .. this.getTryEnd().getIndex()]
}
override string toString() { none() }
override Instruction getASuccessorType(FlowType t) {
result = this.getHandlerStart() and
t instanceof NormalFlow
}
/** Gets the type of the caught exception, if any. */
Type getCaughtType() { cil_handler_type(this, result) }
override Location getLocation() { result = this.getTryStart().getLocation() }
}
/** A handler corresponding to a `finally` block. */
deprecated class FinallyHandler extends Handler, @cil_finally_handler {
override string toString() { result = "finally {...}" }
}
/** A handler corresponding to a `where()` clause. */
deprecated class FilterHandler extends Handler, @cil_filter_handler {
override string toString() { result = "where (...)" }
/** Gets the filter clause - the start of a sequence of instructions to evaluate the filter function. */
Instruction getFilterClause() { cil_handler_filter(this, result) }
override int getPushCount() { result = 1 }
}
/** A handler corresponding to a `catch` clause. */
deprecated class CatchHandler extends Handler, @cil_catch_handler {
override string toString() { result = "catch(" + this.getCaughtType().getName() + ") {...}" }
override int getPushCount() { result = 1 }
}
/** A handler for memory faults. */
deprecated class FaultHandler extends Handler, @cil_fault_handler {
override string toString() { result = "fault {...}" }
}

View File

@@ -1,70 +0,0 @@
/** Provides the `Instruction` class. */
private import CIL
/** An instruction. */
deprecated class Instruction extends Element, ControlFlowNode, DataFlowNode, @cil_instruction {
override string toString() { result = this.getOpcodeName() }
/** Gets a more verbose textual representation of this instruction. */
string toStringExtra() {
result = this.getIndex() + ": " + this.getOpcodeName() + this.getExtraStr()
}
/** Gets the method containing this instruction. */
override MethodImplementation getImplementation() { cil_instruction(this, _, _, result) }
override Method getMethod() { result = this.getImplementation().getMethod() }
/**
* Gets the index of this instruction.
* Instructions are sequenced from 0.
*/
int getIndex() { cil_instruction(this, _, result, _) }
/** Gets the opcode of this instruction. */
final int getOpcode() { cil_instruction(this, result, _, _) }
/** Gets the opcode name of this instruction, for example `ldnull`. */
string getOpcodeName() { none() }
/** Gets an extra field to display for this instruction, if any. */
string getExtra() { none() }
private string getExtraStr() {
if exists(this.getExtra()) then result = " " + this.getExtra() else result = ""
}
/** Gets the declaration accessed by this instruction, if any. */
Declaration getAccess() { cil_access(this, result) }
/** Gets a successor instruction to this instruction. */
override Instruction getASuccessorType(FlowType t) {
t instanceof NormalFlow and
this.canFlowNext() and
result = this.getImplementation().getInstruction(this.getIndex() + 1)
}
/** Holds if this instruction passes control flow into the next instruction. */
predicate canFlowNext() { any() }
/**
* Gets the `i`th handler that applies to this instruction.
* Indexed from 0.
*/
Handler getHandler(int i) {
result.isInScope(this) and
result.getIndex() =
rank[i + 1](int hi | exists(Handler h | h.isInScope(this) and hi = h.getIndex()))
}
override Type getType() { result = ControlFlowNode.super.getType() }
override Location getALocation() {
cil_instruction_location(this, result) // The source code, if available
or
result = this.getImplementation().getLocation() // The containing assembly
}
override Location getLocation() { result = Element.super.getLocation() }
}

View File

@@ -1,263 +0,0 @@
/**
* Provides classes representing various classes of expression
* and other instructions.
*/
private import CIL
private import dotnet
/**
* An instruction that pushes a value onto the stack.
*/
deprecated class Expr extends DotNet::Expr, Instruction, @cil_expr {
override int getPushCount() { result = 1 }
override Type getType() { result = Instruction.super.getType() }
override Method getEnclosingCallable() { result = this.getImplementation().getMethod() }
/**
* The "parent" of a CIL expression is taken to be the instruction
* that consumes the value pushed by this instruction.
*/
override Expr getParent() { this = result.getAnOperand() }
}
/** An instruction that changes control flow. */
deprecated class Branch extends Instruction, @cil_jump {
/** Gets the instruction that is jumped to. */
Instruction getTarget() { cil_jump(this, result) }
override string getExtra() { result = this.getTarget().getIndex() + ":" }
}
/** An instruction that unconditionally jumps to another instruction. */
deprecated class UnconditionalBranch extends Branch, @cil_unconditional_jump {
override Instruction getASuccessorType(FlowType t) {
t instanceof NormalFlow and result = this.getTarget()
}
override predicate canFlowNext() { none() }
}
/** An instruction that jumps to a target based on a condition. */
deprecated class ConditionalBranch extends Branch, @cil_conditional_jump {
override Instruction getASuccessorType(FlowType t) {
t instanceof TrueFlow and result = this.getTarget()
or
t instanceof FalseFlow and result = this.getImplementation().getInstruction(this.getIndex() + 1)
}
override int getPushCount() { result = 0 }
}
/** An expression with two operands. */
deprecated class BinaryExpr extends Expr, @cil_binary_expr {
override int getPopCount() { result = 2 }
}
/** An expression with one operand. */
deprecated class UnaryExpr extends Expr, @cil_unary_expr {
override int getPopCount() { result = 1 }
/** Gets the operand of this unary expression. */
Expr getOperand() { result = this.getOperand(0) }
}
/** A binary expression that compares two values. */
deprecated class ComparisonOperation extends BinaryExpr, @cil_comparison_operation {
override BoolType getType() { exists(result) }
}
/** A binary arithmetic expression. */
deprecated class BinaryArithmeticExpr extends BinaryExpr, @cil_binary_arithmetic_operation {
override Type getType() {
exists(Type t0, Type t1 |
t0 = this.getOperandType(0).getUnderlyingType() and
t1 = this.getOperandType(1).getUnderlyingType()
|
t0 = t1 and result = t0
or
t0.getConversionIndex() < t1.getConversionIndex() and result = t1
or
t0.getConversionIndex() > t1.getConversionIndex() and result = t0
)
}
}
/** A binary bitwise expression. */
deprecated class BinaryBitwiseOperation extends BinaryExpr, @cil_binary_bitwise_operation {
// This is wrong but efficient - should depend on the types of the operands.
override IntType getType() { exists(result) }
}
/** A unary bitwise expression. */
deprecated class UnaryBitwiseOperation extends UnaryExpr, @cil_unary_bitwise_operation {
// This is wrong but efficient - should depend on the types of the operands.
override IntType getType() { exists(result) }
}
/** A unary expression that converts a value from one primitive type to another. */
deprecated class Conversion extends UnaryExpr, @cil_conversion_operation {
/** Gets the expression being converted. */
Expr getExpr() { result = this.getOperand(0) }
}
/** A branch that leaves the scope of a `Handler`. */
deprecated class Leave extends UnconditionalBranch, @cil_leave_any { }
/** An expression that pushes a literal value onto the stack. */
deprecated class Literal extends DotNet::Literal, Expr, @cil_literal {
/** Gets the pushed value. */
override string getValue() { cil_value(this, result) }
override string getExtra() { result = this.getValue() }
}
/** An integer literal. */
deprecated class IntLiteral extends Literal, @cil_ldc_i {
override string getExtra() { none() }
override IntType getType() { exists(result) }
}
/** An expression that pushes a `float`/`Single`. */
deprecated class FloatLiteral extends Literal, @cil_ldc_r { }
/** An expression that pushes a `null` value onto the stack. */
deprecated class NullLiteral extends Literal, @cil_ldnull { }
/** An expression that pushes a string onto the stack. */
deprecated class StringLiteral extends Literal, @cil_ldstr { }
/** A branch with one operand. */
deprecated class UnaryBranch extends ConditionalBranch, @cil_unary_jump {
override int getPopCount() { result = 1 }
override int getPushCount() { result = 0 }
}
/** A branch with two operands. */
deprecated class BinaryBranch extends ConditionalBranch, @cil_binary_jump {
override int getPopCount() { result = 2 }
override int getPushCount() { result = 0 }
}
/** A call. */
deprecated class Call extends Expr, DotNet::Call, @cil_call_any {
/** Gets the method that is called. */
override Method getTarget() { cil_access(this, result) }
override Method getARuntimeTarget() { result = this.getTarget().getAnOverrider*() }
override string getExtra() { result = this.getTarget().getFullyQualifiedName() }
/**
* Gets the return type of the call. Methods that do not return a value
* return the `void` type, `System.Void`, although the value of `getPushCount` is
* 0 in this case.
*/
override Type getType() { result = this.getTarget().getReturnType() }
// The number of items popped/pushed from the stack
// depends on the target of the call.
override int getPopCount() { result = this.getTarget().getCallPopCount() }
override int getPushCount() { result = this.getTarget().getCallPushCount() }
/**
* Holds if this is a "tail call", meaning that control does not return to the
* calling method.
*/
predicate isTailCall() {
this.getImplementation().getInstruction(this.getIndex() - 1) instanceof Opcodes::Tail
}
/** Holds if this call is virtual and could go to an overriding method. */
predicate isVirtual() { none() }
override Expr getRawArgument(int i) { result = this.getOperand(this.getPopCount() - i - 1) }
/** Gets the qualifier of this call, if any. */
Expr getQualifier() { result = this.getRawArgument(0) and not this.getTarget().isStatic() }
override Expr getArgument(int i) {
if this.getTarget().isStatic()
then result = this.getRawArgument(i)
else (
result = this.getRawArgument(i + 1) and i >= 0
)
}
override Expr getArgumentForParameter(DotNet::Parameter param) {
exists(int index |
result = this.getRawArgument(index) and param = this.getTarget().getRawParameter(index)
)
}
}
/** A tail call. */
deprecated class TailCall extends Call {
TailCall() { this.isTailCall() }
override predicate canFlowNext() { none() }
}
/** A call to a static target. */
deprecated class StaticCall extends Call {
StaticCall() { not this.isVirtual() }
}
/** A call to a virtual target. */
deprecated class VirtualCall extends Call {
VirtualCall() { this.isVirtual() }
}
/** A read of an array element. */
deprecated class ReadArrayElement extends BinaryExpr, @cil_read_array {
/** Gets the array being read. */
Expr getArray() { result = this.getOperand(1) }
/** Gets the index into the array. */
Expr getArrayIndex() { result = this.getOperand(0) }
}
/** A write of an array element. */
deprecated class WriteArrayElement extends Instruction, @cil_write_array {
override int getPushCount() { result = 0 }
override int getPopCount() { result = 3 }
}
/** A `return` statement. */
deprecated class Return extends Instruction, @cil_ret {
/** Gets the expression being returned, if any. */
Expr getExpr() { result = this.getOperand(0) }
override predicate canFlowNext() { none() }
}
/** A `throw` statement. */
deprecated class Throw extends Instruction, DotNet::Throw, @cil_throw_any {
override Expr getExpr() { result = this.getOperand(0) }
/** Gets the type of the exception being thrown. */
Type getExceptionType() { result = this.getOperandType(0) }
override predicate canFlowNext() { none() }
}
/** Stores a value at an address/location. */
deprecated class StoreIndirect extends Instruction, @cil_stind {
override int getPopCount() { result = 2 }
/** Gets the location to store the value at. */
Expr getAddress() { result = this.getOperand(1) }
/** Gets the value to store. */
Expr getExpr() { result = this.getOperand(0) }
}
/** Loads a value from an address/location. */
deprecated class LoadIndirect extends UnaryExpr, @cil_ldind { }

File diff suppressed because it is too large Load Diff

View File

@@ -1,296 +0,0 @@
/**
* Provides classes for methods.
*
* Methods and implementations are different because there can be several implementations for the same
* method in different assemblies. It is not really possible to guarantee which methods will be loaded
* at run-time.
*/
private import CIL
private import dotnet
/**
* An implementation of a method in an assembly.
*/
deprecated class MethodImplementation extends EntryPoint, @cil_method_implementation {
/** Gets the method of this implementation. */
Method getMethod() { cil_method_implementation(this, result, _) }
override MethodImplementation getImplementation() { result = this }
/** Gets the location of this implementation. */
override Assembly getLocation() { cil_method_implementation(this, _, result) }
/** Gets the instruction at index `index`. */
Instruction getInstruction(int index) { cil_instruction(result, _, index, this) }
/** Gets the `n`th local variable of this implementation. */
LocalVariable getLocalVariable(int n) { cil_local_variable(result, this, n, _) }
/** Gets a local variable of this implementation, if any. */
LocalVariable getALocalVariable() { result = this.getLocalVariable(_) }
/** Gets an instruction in this implementation, if any. */
Instruction getAnInstruction() { result = this.getInstruction(_) }
/** Gets the total number of instructions in this implementation. */
int getNumberOfInstructions() { result = count(this.getAnInstruction()) }
/** Gets the `i`th handler in this implementation. */
Handler getHandler(int i) { result.getImplementation() = this and result.getIndex() = i }
/** Gets a handler in this implementation, if any. */
Handler getAHandler() { result.getImplementation() = this }
override Instruction getASuccessorType(FlowType t) {
t instanceof NormalFlow and result.getImplementation() = this and result.getIndex() = 0
}
/** Gets the maximum stack size of this implementation. */
int getStackSize() { cil_method_stack_size(this, result) }
override string toString() { result = this.getMethod().toString() }
/** Gets a string representing the disassembly of this implementation. */
string getDisassembly() {
result =
concat(Instruction i |
i = this.getAnInstruction()
|
i.toStringExtra(), ", " order by i.getIndex()
)
}
}
/**
* A method, which corresponds to any callable in C#, including constructors,
* destructors, operators, accessors and so on.
*/
deprecated class Method extends DotNet::Callable, Element, Member, TypeContainer, DataFlowNode,
CustomModifierReceiver, Parameterizable, @cil_method
{
/**
* Gets a method implementation, if any. Note that there can
* be several implementations in different assemblies.
*/
MethodImplementation getAnImplementation() { result.getMethod() = this }
/** Gets the "best" implementation of this method, if any. */
BestImplementation getImplementation() { result = this.getAnImplementation() }
override Method getMethod() { result = this }
override string getName() { cil_method(this, result, _, _) }
override string getUndecoratedName() { result = this.getName() }
override string toString() { result = this.getName() }
override Type getDeclaringType() { cil_method(this, _, result, _) }
override Location getLocation() { result = Element.super.getLocation() }
override Location getALocation() { cil_method_location(this.getUnboundMethod+(), result) }
override MethodParameter getParameter(int n) {
if this.isStatic()
then result = this.getRawParameter(n)
else (
result = this.getRawParameter(n + 1) and n >= 0
)
}
override Type getType() { result = this.getReturnType() }
/** Gets the return type of this method. */
override Type getReturnType() { cil_method(this, _, _, result) }
/** Holds if the return type is `void`. */
predicate returnsVoid() { this.getReturnType() instanceof VoidType }
/** Gets the number of stack items pushed in a call to this method. */
int getCallPushCount() { if this.returnsVoid() then result = 0 else result = 1 }
/** Gets the number of stack items popped in a call to this method. */
int getCallPopCount() { result = count(this.getRawParameter(_)) }
/** Gets a method called by this method. */
Method getACallee() { result = this.getImplementation().getAnInstruction().(Call).getTarget() }
/** Holds if this method is `virtual`. */
predicate isVirtual() { cil_virtual(this) }
/** Holds if the name of this method is special, for example an operator. */
predicate isSpecial() { cil_specialname(this) }
/** Holds of this method is marked as secure. */
predicate isSecureObject() { cil_requiresecobject(this) }
/** Holds if the method does not override an existing method. */
predicate isNew() { cil_newslot(this) }
override predicate isStatic() { cil_static(this) }
/** Gets the unbound declaration of this method, or the method itself. */
Method getUnboundMethod() { cil_method_source_declaration(this, result) }
override Method getUnboundDeclaration() { result = this.getUnboundMethod() }
/** Holds if this method is an instance constructor. */
predicate isInstanceConstructor() { this.isSpecial() and this.getName() = ".ctor" }
/** Holds if this method is a static class constructor. */
predicate isStaticConstructor() { this.isSpecial() and this.getName() = ".cctor" }
/** Holds if this method is a constructor (static or instance). */
predicate isConstructor() { this.isStaticConstructor() or this.isInstanceConstructor() }
/** Holds if this method is a destructor/finalizer. */
predicate isFinalizer() {
this.getOverriddenMethod*().hasFullyQualifiedName("System", "Object", "Finalize")
}
/** Holds if this method is an operator. */
predicate isOperator() { this.isSpecial() and this.getName().matches("op\\_%") }
/** Holds if this method is a getter. */
predicate isGetter() { this.isSpecial() and this.getName().matches("get\\_%") }
/** Holds if this method is a setter. */
predicate isSetter() { this.isSpecial() and this.getName().matches("set\\_%") }
/** Holds if this method is an adder/add event accessor. */
predicate isAdder() { this.isSpecial() and this.getName().matches("add\\_%") }
/** Holds if this method is a remover/remove event accessor. */
predicate isRemove() { this.isSpecial() and this.getName().matches("remove\\_%") }
/** Holds if this method is an implicit conversion operator. */
predicate isImplicitConversion() { this.isSpecial() and this.getName() = "op_Implicit" }
/** Holds if this method is an explicit conversion operator. */
predicate isExplicitConversion() { this.isSpecial() and this.getName() = "op_Explicit" }
/** Holds if this method is a conversion operator. */
predicate isConversion() { this.isImplicitConversion() or this.isExplicitConversion() }
/**
* Gets a method that is overridden, either in a base class
* or in an interface.
*/
Method getOverriddenMethod() { cil_implements(this, result) }
/** Gets a method that overrides this method, if any. */
final Method getAnOverrider() { result.getOverriddenMethod() = this }
override predicate hasBody() { exists(this.getImplementation()) }
override predicate canReturn(DotNet::Expr expr) {
exists(Return ret | ret.getImplementation() = this.getImplementation() and expr = ret.getExpr())
}
}
/** A destructor/finalizer. */
deprecated class Destructor extends Method, DotNet::Destructor {
Destructor() { this.isFinalizer() }
}
/** A constructor. */
deprecated class Constructor extends Method, DotNet::Constructor {
Constructor() { this.isConstructor() }
}
/** A static/class constructor. */
deprecated class StaticConstructor extends Constructor {
StaticConstructor() { this.isStaticConstructor() }
}
/** An instance constructor. */
deprecated class InstanceConstructor extends Constructor {
InstanceConstructor() { this.isInstanceConstructor() }
}
/** A method that always returns the `this` parameter. */
deprecated class ChainingMethod extends Method {
ChainingMethod() {
forex(Return ret | ret = this.getImplementation().getAnInstruction() |
ret.getExpr() instanceof ThisAccess
)
}
}
/** An accessor. */
abstract deprecated class Accessor extends Method {
/** Gets the property declaring this accessor. */
abstract Property getProperty();
}
/** A getter. */
deprecated class Getter extends Accessor {
Getter() { cil_getter(_, this) }
override Property getProperty() { cil_getter(result, this) }
}
/**
* A method that does nothing but retrieve a field.
* Note that this is not necessarily a property getter.
*/
deprecated class TrivialGetter extends Method {
TrivialGetter() {
exists(MethodImplementation impl | impl = this.getAnImplementation() |
impl.getInstruction(0) instanceof ThisAccess and
impl.getInstruction(1) instanceof FieldReadAccess and
impl.getInstruction(2) instanceof Return
)
}
/** Gets the underlying field of this getter. */
Field getField() {
this.getImplementation().getAnInstruction().(FieldReadAccess).getTarget() = result
}
}
/** A setter. */
deprecated class Setter extends Accessor {
Setter() { cil_setter(_, this) }
override Property getProperty() { cil_setter(result, this) }
/** Holds if this setter is an `init` accessor. */
predicate isInitOnly() {
exists(Type t | t.hasFullyQualifiedName("System.Runtime.CompilerServices", "IsExternalInit") |
this.hasRequiredCustomModifier(t)
)
}
}
/**
* A method that does nothing but set a field.
* This is not necessarily a property setter.
*/
deprecated class TrivialSetter extends Method {
TrivialSetter() {
exists(MethodImplementation impl | impl = this.getAnImplementation() |
impl.getInstruction(0) instanceof ThisAccess and
impl.getInstruction(1).(ParameterReadAccess).getTarget().getIndex() = 1 and
impl.getInstruction(2) instanceof FieldWriteAccess
)
}
/** Gets the underlying field of this setter. */
Field getField() {
result = this.getImplementation().getAnInstruction().(FieldWriteAccess).getTarget()
}
}
/** An alias for `Method` for compatibility with the C# data model. */
deprecated class Callable = Method;
/** An operator. */
deprecated class Operator extends Method {
Operator() { this.isOperator() }
/** Gets the name of the implementing method (for compatibility with C# data model). */
string getFunctionName() { result = this.getName() }
}

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