Compare commits

...

694 Commits

Author SHA1 Message Date
Pierre
6e4ad58a80 Merge pull request #14889 from github/changedocs/2.15.3
Fix changelog docs based on latest generator version
2023-11-23 15:43:02 +01:00
Pierre
bff86ed210 Fix changelog docs based on latest generator version 2023-11-23 13:53:14 +01:00
Pierre
60ebe3b179 Merge pull request #14876 from github/changedocs/2.15.3
Add combined changelogs for 2.15.3 and backfill historic versions
2023-11-22 16:22:56 +01:00
Pierre
9b9a78851d Add combined changelogs for 2.15.3 and backfill historic versions 2023-11-22 15:05:17 +01:00
Arthur Baars
ff65ffafb0 Merge pull request #14830 from aibaars/csharp/fixintegrationtests
C# fix integration tests
2023-11-17 11:17:31 +01:00
Michael B. Gale
97402fdf36 C#: Fix dotnet_test_mstest 2023-11-17 10:35:14 +01:00
Michael Nebel
2662a4c651 C#: Fix the dotnet pack integration test. 2023-11-17 10:35:14 +01:00
Arthur Baars
dce03569e5 Merge pull request #14813 from github/release-prep/2.15.3
Release preparation for version 2.15.3
2023-11-16 18:42:17 +01:00
github-actions[bot]
6ec9b95072 Release preparation for version 2.15.3 2023-11-16 13:07:16 +00:00
Arthur Baars
641646ac08 Rename change note 2023-11-16 14:04:25 +01:00
Tom Hvitved
75f42f4614 Merge pull request #14783 from hvitved/ruby/hash-array-literal
Ruby: Include more nodes in `{Hash,Array}LiteralCfgNode`
2023-11-16 13:51:35 +01:00
Henry Mercer
0c1fb8c881 Merge pull request #14811 from github/henrymercer/remove-lines-of-non-user-code-from-summary
Remove LoC metrics from the analysis summary
2023-11-16 12:30:55 +00:00
Rasmus Wriedt Larsen
4f9303eb02 Merge pull request #14790 from RasmusWL/clean-tests
Python: Accept new ordering of query predicates in `.expected`
2023-11-16 13:23:35 +01:00
Tom Hvitved
2c23dacca1 Ruby: Add more hash/array literal tests 2023-11-16 12:58:53 +01:00
Henry Mercer
de83929a60 Remove LoC metrics from the analysis summary 2023-11-16 11:36:44 +00:00
Stephan Brandauer
f1001374fd Merge pull request #14642 from github/kaeluka/publish-automodel-querypack-007
Java: Publish Automodel query pack 0.0.7
2023-11-16 11:50:32 +01:00
Rasmus Wriedt Larsen
25d3af9236 Merge branch 'main' into clean-tests 2023-11-16 11:21:01 +01:00
Jeroen Ketema
1f3f1b5ec4 Merge pull request #14809 from MathiasVP/move-change-note
C++: Move change note
2023-11-16 11:14:14 +01:00
Mathias Vorreiter Pedersen
5c0fb2030d C++: Move change note. 2023-11-16 09:57:08 +00:00
Rasmus Wriedt Larsen
71ef98584d Merge pull request #14791 from RasmusWL/python-3.12
Python: Update `.expected` to support Python 3.12
2023-11-16 10:42:48 +01:00
Tom Hvitved
6bba191407 Merge pull request #14710 from hvitved/type-tracking/prepare-ruby
Prepare shared type tracking library for adoption by Ruby
2023-11-16 10:34:32 +01:00
Rasmus Wriedt Larsen
df144f3a1e Merge pull request #14406 from amammad/amammad-python-FileSystemAccess
Python: New FileSystem Access
2023-11-16 10:25:34 +01:00
Rasmus Wriedt Larsen
a46dc55e84 Merge branch 'main' into python-3.12 2023-11-16 09:34:06 +01:00
Tamás Vajk
14268f3c63 Merge pull request #14792 from tamasvajk/standalone/assembly-attribute
C#: Fix assembly attribute extraction in standalone mode
2023-11-16 08:09:14 +01:00
Sam Browning
408ba517e5 Merge pull request #14776 from github/sabrowning1/queries-panel-language-selector
Add content for the queries panel and language selector
2023-11-15 17:30:21 -05:00
Mathias Vorreiter Pedersen
4d4ca6b948 Merge pull request #14794 from MathiasVP/catch-more-return-stack-allocated-memory
C++: Catch more returns of stack-allocated memory
2023-11-15 19:23:24 +00:00
Sam Browning
d443354651 Apply feedback and fix syntax 2023-11-15 11:35:33 -05:00
Tom Hvitved
57f6859ddc Shared: Update type tracking consistency checks 2023-11-15 17:08:05 +01:00
Tom Hvitved
5f087f0084 Shared: Port features from Ruby's type tracking library to the shared library
- Cache relevant predicates.
- Expose some predicates and classes (only exposed internally).
- Make some top-level `inline_late` predicates member predicates.
- Actually eliminate type check in `flowsTo`.
- Fix bug in `getACompatibleTypeTracker`.
- Adopt the `CallGraphConstruction` module.
2023-11-15 17:08:05 +01:00
Tom Hvitved
f66f7ce8d7 Shared: Split up TypeTracking.qll into two files 2023-11-15 17:07:27 +01:00
Jeroen Ketema
f22979f4b6 Merge pull request #14561 from jketema/rewrite-uncontrolled-process-operation
C++: Rewrite `cpp/uncontrolled-process-operation` to not use `DefaultTaintTracking`
2023-11-15 16:03:58 +01:00
Jeroen Ketema
46e6e72593 C++: Address review comments 2023-11-15 14:57:53 +01:00
Jeroen Ketema
92c18960c5 C++: Rewrite cpp/uncontrolled-process-operation to not use DefaultTaintTracking 2023-11-15 14:57:53 +01:00
Rasmus Wriedt Larsen
e349891cff Python: Apply suggestions from code review 2023-11-15 14:35:52 +01:00
Rasmus Wriedt Larsen
e02c32f3d4 Python: options file was not enough, split into 2/3
I reckon this is due to the Python 3 version used by the Python 2 tests
is different from 3.12, so even with --lang=3 the tests are still using
an incompatible version :(
2023-11-15 14:24:11 +01:00
Rasmus Wriedt Larsen
0f1dc9b2d9 Python: Add missing options file 2023-11-15 13:24:08 +01:00
Rasmus Wriedt Larsen
ae6c95ff95 Python: Fix asyncio.coroutine deprecation
Was removed in 3.11, see https://docs.python.org/3.10/library/asyncio-task.html#asyncio.coroutine

I couldn't make the __awwait__ actually give the result to the agen function...

I also tried looking into
https://docs.python.org/3/library/types.html#types.coroutine, but also
failed to make that work.

Without the Future, such as doing `yield SOURCE` inside `__await__` it
complains `RuntimeError: Task got bad yield: 'source'`
2023-11-15 13:24:08 +01:00
Mathias Vorreiter Pedersen
bae7e10e46 C++: Also add MSVC-related 'alloca'-like functions. 2023-11-15 12:07:17 +00:00
Mathias Vorreiter Pedersen
ec63099c54 C++: Add change note. 2023-11-15 11:57:09 +00:00
Mathias Vorreiter Pedersen
2b8b5cf1b8 C++: Accept test changes. 2023-11-15 11:52:14 +00:00
Mathias Vorreiter Pedersen
6730f57d5c C++: Also flag up 'alloca' and friends. 2023-11-15 11:51:57 +00:00
Mathias Vorreiter Pedersen
118d50236f C++: Add failing tests. 2023-11-15 11:48:37 +00:00
Tamas Vajk
7a001f4905 C#: Fix assembly attribute extraction in standalone mode 2023-11-15 12:21:03 +01:00
Owen Mansel-Chan
803ed20962 Merge pull request #14778 from owen-mc/go/improve-value-flow-through-arrays
Go: improve value flow through arrays
2023-11-15 11:13:15 +00:00
Rasmus Wriedt Larsen
4256fbf11a Python: Accept changes from Python 3.12 2023-11-15 11:42:38 +01:00
Rasmus Wriedt Larsen
f3dd002ba9 Python: Copy tests to Python 3 2023-11-15 11:42:38 +01:00
Rasmus Wriedt Larsen
f9e9ae91f7 Python: Move tests that would change under Python 3.12 to lang specific directory
This moves the tests to Python 2, next we copy them to Python 3.
2023-11-15 11:42:38 +01:00
Rasmus Wriedt Larsen
23419ee634 Python: Update .expected to support Python 3.12
You might wonder why the number of lines changed, but it's due to `tty`
module receiving its' first update since 2001, so the actual number of
lines DID change :phew:

https://github.com/python/cpython/commits/3.12/Lib/tty.py

Since there is now a difference between Python 2 and Python 3, we need to restrict the lines of code test to only run as Python 3.
2023-11-15 11:42:38 +01:00
Mathias Vorreiter Pedersen
b8f0f85840 Merge pull request #14784 from MathiasVP/no-dtt-in-tainted-arithmetic
C++: Rewrite `cpp/tainted-arithmetic` away from `DefaultTaintTracking`
2023-11-15 10:19:25 +00:00
Rasmus Wriedt Larsen
69453aa144 Python: Fix missing newline in .expected 2023-11-15 10:10:23 +01:00
Rasmus Wriedt Larsen
55f5b26ba6 Python: Accept new ordering of query predicates in .expected 2023-11-15 10:09:54 +01:00
Rasmus Wriedt Larsen
721bde1ce8 Python: Delete orphaned .expected files 2023-11-15 09:59:26 +01:00
Rasmus Wriedt Larsen
2e9d548083 Merge pull request #14706 from RasmusWL/class-attribute-flow
Python: Add basic flow for class attributes
2023-11-15 09:06:25 +01:00
Owen Mansel-Chan
83d1fc33e1 Add change note 2023-11-14 23:16:32 +00:00
Erik Krogh Kristensen
14e51627c5 Merge pull request #14419 from rvermeulen/rvermeulen/javascript-adjust-security-severity
JavaScript: Adjust XSS and log injection query severities
2023-11-14 21:34:25 +01:00
Remco Vermeulen
52540b42fc Merge branch 'main' into rvermeulen/javascript-adjust-security-severity 2023-11-14 11:21:38 -08:00
Remco Vermeulen
6bd7047e41 Restore XssThroughDom.ql's severity 2023-11-14 11:20:51 -08:00
AlexDenisov
57f1f5b829 Merge pull request #14768 from github/alexdenisov/move-semantics
Swift: extract AST nodes related to move semantics
2023-11-14 19:13:27 +01:00
Mathias Vorreiter Pedersen
bff93c4484 Merge branch 'main' into no-dtt-in-tainted-arithmetic 2023-11-14 17:12:34 +00:00
Geoffrey White
0342b3eba2 Merge pull request #14772 from geoffw0/webview
Swift: Use TaintInheritingContent in WebView.qll
2023-11-14 16:29:32 +00:00
Geoffrey White
d28e7920b3 Merge pull request #14773 from geoffw0/fixmodel
Swift: Fix odds and ends
2023-11-14 16:28:33 +00:00
Tamás Vajk
331ca61be9 Merge pull request #14789 from tamasvajk/autobuild/arm-nuget-restore
C#: Do not call nuget.exe on Apple Silicon
2023-11-14 17:13:42 +01:00
Alex Denisov
559b965e74 Swift: add change note 2023-11-14 16:11:28 +01:00
Felicity Chapman
6299b844f8 Merge pull request #14785 from github/felicitymay-security-severity
Update metadata-for-codeql-queries.rst
2023-11-14 14:13:53 +00:00
Sam Browning
4385b316c0 Apply feedback from code review 2023-11-14 09:10:07 -05:00
Sam Browning
b1dc6099ff Apply feedback from code review 2023-11-14 09:01:54 -05:00
Sam Browning
15099b3db0 Update docs/codeql/codeql-for-visual-studio-code/analyzing-your-projects.rst
Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com>
2023-11-14 08:57:52 -05:00
Tamas Vajk
8334c6db91 C#: Do not call nuget.exe on Apple Silicon 2023-11-14 14:50:29 +01:00
Alex Denisov
1c75e5b2a6 Swift: add database migration scripts for move semantics 2023-11-14 14:35:58 +01:00
Mathias Vorreiter Pedersen
1623bba18a Merge branch 'main' into no-dtt-in-tainted-arithmetic 2023-11-14 13:35:15 +00:00
Tom Hvitved
475d8da342 Ruby: Include more nodes in {Hash,Array}LiteralCfgNode 2023-11-14 13:50:46 +01:00
Tom Hvitved
ae09499905 Merge pull request #14781 from hvitved/ruby/ssa-unitialized-to-string
Ruby: Include name of variable in `UninitializedDefinition.toString`
2023-11-14 13:49:27 +01:00
Mathias Vorreiter Pedersen
c950e26b3e C++: Rewrite 'cpp/cpp/tainted-arithmetic' away from DefaultTaintTracking. 2023-11-14 12:19:12 +00:00
Felicity Chapman
f75c062949 Update metadata-for-codeql-queries.rst
Replace link to blog with trackable GH.io link
2023-11-14 12:06:44 +00:00
Mathias Vorreiter Pedersen
f22d87b7c7 Merge pull request #14771 from MathiasVP/fix-missing-unbounded-write-results
C++: Fix missing results in `cpp/unbounded-write`
2023-11-14 12:03:13 +00:00
Tamás Vajk
e11a68803e Merge pull request #14782 from github/criemen/disable-int-test
Disable the nuget standalone dependencies test on ARM-osx.
2023-11-14 12:32:48 +01:00
Owen Mansel-Chan
45faed057c Improve SliceExpr documentation 2023-11-14 11:25:16 +00:00
Tom Hvitved
f1b67ade9b Ruby: Include name of variable in UninitializedDefinition.toString 2023-11-14 11:33:59 +01:00
Cornelius Riemenschneider
f9ae7c5454 Disable the nuget standalone dependencies test on ARM-osx.
The test is failing currently, and that needs further investigation.
This is a temporary workaround to allow us to continue to work on
some necessary infrastructure investments around these tests.
2023-11-14 11:13:55 +01:00
Geoffrey White
296dee90dd Merge remote-tracking branch 'upstream/main' into fixmodel 2023-11-14 09:38:14 +00:00
Mathias Vorreiter Pedersen
967bbbc1a7 C++: Block flow out of sinks that are qualifiers. This removes the new result duplication and keeps the new result. 2023-11-14 09:29:47 +00:00
Tamás Vajk
28a5a1d507 Merge pull request #14760 from tamasvajk/apple-silicon-check
C#: Change IsARM to Apple silicon check
2023-11-14 10:27:42 +01:00
Tamas Vajk
5b38ba87df Code quality improvement 2023-11-14 08:08:46 +01:00
Erik Krogh Kristensen
db42b60015 Merge pull request #14779 from github/dependabot/cargo/ql/tracing-subscriber-0.3.18
Bump tracing-subscriber from 0.3.17 to 0.3.18 in /ql
2023-11-14 07:57:55 +01:00
dependabot[bot]
f8c8d59cb5 Bump tracing-subscriber from 0.3.17 to 0.3.18 in /ql
Bumps [tracing-subscriber](https://github.com/tokio-rs/tracing) from 0.3.17 to 0.3.18.
- [Release notes](https://github.com/tokio-rs/tracing/releases)
- [Commits](https://github.com/tokio-rs/tracing/compare/tracing-subscriber-0.3.17...tracing-subscriber-0.3.18)

---
updated-dependencies:
- dependency-name: tracing-subscriber
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-14 03:56:51 +00:00
Owen Mansel-Chan
c8779d0d0b Fix another test
No change in alerts, just 3 extra nodes.
2023-11-13 23:56:25 +00:00
Owen Mansel-Chan
28160e418c Update tests 2023-11-13 23:26:30 +00:00
Owen Mansel-Chan
ed349f7d6b Improve value flow through arrays 2023-11-13 23:26:16 +00:00
Sam Browning
fa569dcef4 Delete requirements.txt 2023-11-13 17:28:14 -05:00
Sam Browning
040d971588 Merge branch 'main' into sabrowning1/queries-panel-language-selector 2023-11-13 17:27:35 -05:00
Sam Browning
e95bfc816e Clarify that queries run against selected database 2023-11-13 17:15:41 -05:00
Sam Browning
44935cef63 Tweak for style 2023-11-13 17:08:31 -05:00
Sam Browning
190050f577 Tweak formatting and styling 2023-11-13 16:52:33 -05:00
Sam Browning
458baeff32 Add content on queries panel and language selector 2023-11-13 15:59:51 -05:00
Geoffrey White
c14d4042e0 Merge pull request #14748 from geoffw0/pathinjectionsinks
Swift: Add more path injection sinks
2023-11-13 20:15:16 +00:00
Geoffrey White
5a451e964d Swift: Model mainDocumentURL. 2023-11-13 19:51:51 +00:00
Geoffrey White
b157d73c10 Swift: Make the URLRequest test more accurate. 2023-11-13 19:36:03 +00:00
Geoffrey White
985d1990eb Swift: Fix typo. 2023-11-13 18:55:11 +00:00
Geoffrey White
463096e4be Swift: Modernize tainted content in WebView.qll. 2023-11-13 18:30:40 +00:00
Geoffrey White
892beeab6d Swift: Add test case. 2023-11-13 18:25:59 +00:00
Geoffrey White
9ec2f9204b Swift: Correct components(separatedBy:) models. 2023-11-13 17:43:21 +00:00
Mathias Vorreiter Pedersen
c73e6f1fa8 C++: Accept more test changes. 2023-11-13 16:51:07 +00:00
Mathias Vorreiter Pedersen
9aafbfce13 C++: Fix test annotation. 2023-11-13 16:17:18 +00:00
Mathias Vorreiter Pedersen
cc6268339b C++: Fix failing test and accept test cases. 2023-11-13 15:57:22 +00:00
Mathias Vorreiter Pedersen
834b07e6ad C++: Add failing tests. 2023-11-13 15:54:41 +00:00
Mathias Vorreiter Pedersen
8be6aeda3e Merge pull request #14769 from MathiasVP/fix-nonterminating-test
C++: Fix nonterminating test
2023-11-13 15:49:39 +00:00
Owen Mansel-Chan
359dcf37e9 Merge pull request #14649 from Kwstubbs/go-cors
Go: Add Cors Gin Support
2023-11-13 15:46:59 +00:00
Mathias Vorreiter Pedersen
eb263e747f C++: Make sure the test terminates. 2023-11-13 15:25:48 +00:00
Mathias Vorreiter Pedersen
bc576f658e C++: Add a test that fails because of a non-terminating test that dominates this one. 2023-11-13 15:24:56 +00:00
Geoffrey White
6f56a656e4 Merge pull request #14761 from geoffw0/moderntest
Swift: Update the inline dataflow tests
2023-11-13 14:59:08 +00:00
Alex Denisov
031f453af8 Swift: CFG for Copy/Consume expressions 2023-11-13 15:55:37 +01:00
Alex Denisov
002f2a0985 Swift: extract BorrowExpr 2023-11-13 15:55:37 +01:00
Alex Denisov
d21e27c717 Swift: extract ConsumeExpr 2023-11-13 15:55:37 +01:00
Alex Denisov
30e4822fb7 Swift: extract CopyExpr 2023-11-13 15:55:37 +01:00
Owen Mansel-Chan
d931ade182 Merge pull request #13366 from maikypedia/maikypedia/go-ldap-improper-auth
Go: Add Improper LDAP Authentication query (CWE-287)
2023-11-13 14:48:19 +00:00
Sam Browning
ed9a0ea155 Merge branch 'main' of https://github.com/github/codeql 2023-11-13 08:40:42 -05:00
Geoffrey White
c3577b34d3 Swift: Clean up logic. 2023-11-13 12:37:35 +00:00
Geoffrey White
e4da8da5d9 Swift: Update the example code. 2023-11-13 12:33:20 +00:00
Tamas Vajk
b455b2c1a6 C#: Change IsARM to Apple silicon check 2023-11-13 13:20:13 +01:00
Anders Schack-Mulligen
dc4dda1dbc Merge pull request #14757 from aschackmull/rangeanalysis/simplify
Rangeanalysis: Misc simplifications
2023-11-13 13:16:04 +01:00
Geoffrey White
098ea50068 Swift: Repair non-inline dataflow test. 2023-11-13 12:09:08 +00:00
Geoffrey White
6e291711ac Swift: Update just enough tests to prove that that source labels are working. 2023-11-13 11:47:24 +00:00
Geoffrey White
fca6ccd2f1 Swift: Remove more unused code. 2023-11-13 11:47:22 +00:00
AlexDenisov
291bb2210c Merge pull request #14759 from github/alexdenisov/experimental-tuple
Swift: mark BuiltinTuple as experimental
2023-11-13 12:24:06 +01:00
Geoffrey White
4bf717c3e4 Swift: Use InlineFlowTest.qll in the data flow inline tests, so that we have less code duplication and can use flow labels. 2023-11-13 11:06:05 +00:00
Geoffrey White
d15c46836b Swift: Add features tom InlineFlowTest.qll: extended source/sink names, custom flow tags, use of line-numbers as a fallback value. 2023-11-13 10:55:17 +00:00
Alex Denisov
c0fce80b7d Swift: mark BuiltinTuple as experimental 2023-11-13 11:34:51 +01:00
Cornelius Riemenschneider
1b7e3814b0 Merge pull request #14719 from github/criemen/java-int-tests
Java integration tests: More preparations to be executed on GH M1 machines
2023-11-13 11:16:51 +01:00
Anders Schack-Mulligen
bf6cfd3bef Rangeanalysis: Simplify api. 2023-11-13 10:35:44 +01:00
Anders Schack-Mulligen
30aefabb2a Rangeanalysis: Rename predicate. 2023-11-13 10:35:44 +01:00
Anders Schack-Mulligen
f05b75e04f Rangeanalysis: RIP standard order. 2023-11-13 10:35:44 +01:00
Anders Schack-Mulligen
c28f54a78b Rangeanalysis: Remove superfluous pragmas. These appear useless after the abolishment of the different delta orders. 2023-11-13 10:35:44 +01:00
Anders Schack-Mulligen
66b03bfb12 Java: Remove unused import 2023-11-13 10:35:44 +01:00
Anders Schack-Mulligen
71e25521cf Rangeanalysis: Use SsaReadPositionBlock.getAnSsaRead. 2023-11-13 10:35:44 +01:00
Anders Schack-Mulligen
27e6173bb7 C++: Remove SemSsaExplicitUpdate.getSourceExpr. 2023-11-13 10:35:43 +01:00
Anders Schack-Mulligen
3a73faf061 Rangeanalysis: Remove unused getAlternateType predicates. 2023-11-13 10:35:43 +01:00
AlexDenisov
352ec91a08 Merge pull request #14756 from github/alexdenisov/do-not-extract-non-ast-types
Swift: do not extract non-AST types, NFC
2023-11-13 10:35:00 +01:00
Anders Schack-Mulligen
00549e36ed Merge pull request #14742 from aschackmull/rangeanalysis/share-util-3
Java/C++/Rangeanalysis: Share more range analysis utility predicates.
2023-11-13 10:19:41 +01:00
Alex Denisov
b385ddbab1 Swift: do not extract non-AST types 2023-11-13 09:12:22 +01:00
AlexDenisov
f599c6d8a9 Merge pull request #14734 from github/alexdenisov/parameter-packs
Swift: extract parameter packs
2023-11-13 08:44:39 +01:00
Paolo Tranquilli
df967ce43f Merge pull request #14750 from github/alexdenisov/update-wordings
Swift: update wordings in a downgrade script
2023-11-13 07:00:39 +01:00
Maiky
6e533c6284 Import PathGraph 2023-11-12 18:22:14 +01:00
Maiky
2b1b4cd85d Remove unused LdapConn 2023-11-12 18:18:43 +01:00
Maiky
5280d69500 Change to DataFlow::ConfigSig 2023-11-12 18:17:09 +01:00
Maiky
39ed7876c3 Merge branch 'github:main' into maikypedia/go-ldap-improper-auth 2023-11-12 18:14:05 +01:00
Maiky
882280309f equalityAsSanitizerGuard and add empty string comment 2023-11-12 17:42:56 +01:00
Mathias Vorreiter Pedersen
01a074c146 Merge pull request #14749 from MathiasVP/less-code-duplication 2023-11-10 19:45:56 +00:00
Geoffrey White
d56625cb8b Swift: Rename the capture test to look more like the others. 2023-11-10 17:59:44 +00:00
Alex Denisov
8f10667ee1 Swift: update wordings in a downgrade script 2023-11-10 18:10:43 +01:00
AlexDenisov
837cdc8301 Merge pull request #14745 from github/alexdenisov/parameter-packs-db-upgrade
Swift: parameter packs migration scripts
2023-11-10 18:07:10 +01:00
Jeroen Ketema
3a62628938 Merge pull request #14735 from jketema/strl
C++: Add models for `strlcpy` and `strlcat`
2023-11-10 17:51:59 +01:00
Mathias Vorreiter Pedersen
9062fb666a C++: Move a couple of predicates to 'Node0Impl'. 2023-11-10 16:26:03 +00:00
Jeroen Ketema
b48d483eba C++: Add change note 2023-11-10 17:25:19 +01:00
Geoffrey White
c327f0f0a7 Merge branch 'main' into pathinjectionsinks 2023-11-10 16:04:56 +00:00
Alex Denisov
393aad5935 Swift: downgrade parameter packs 2023-11-10 16:22:09 +01:00
Geoffrey White
8f141cb157 Swift: Change note. 2023-11-10 15:13:51 +00:00
Geoffrey White
5a09a325f2 Swift: Add heuristic path injection sinks. 2023-11-10 15:13:51 +00:00
Mathias Vorreiter Pedersen
18c0bcec0b Merge pull request #14669 from MathiasVP/no-dtt-in-unbounded-write
C++: Rewrite `cpp/unbounded-write` away from `DefaultTaintTracking`
2023-11-10 15:08:42 +00:00
Rasmus Wriedt Larsen
5fc8a00487 Python: Rename test function 2023-11-10 15:58:20 +01:00
Rasmus Wriedt Larsen
b3feb4d7e9 Update python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll
Co-authored-by: yoff <lerchedahl@gmail.com>
2023-11-10 15:57:00 +01:00
Mathias Vorreiter Pedersen
2ceb4cffbc Merge pull request #14736 from MathiasVP/fix-global-indirect-flow
C++: Fix indirect global-variable flow
2023-11-10 14:25:23 +00:00
Anders Schack-Mulligen
0d8986cfad Java: Accept test changes. 2023-11-10 14:04:45 +01:00
Jeroen Ketema
c71bdce2d0 Merge pull request #14744 from jketema/fgets
C++: Fix `hasRemoteFlowSource` for `fgets`
2023-11-10 14:03:40 +01:00
Mathias Vorreiter Pedersen
4f6b6b4a6f Merge branch 'main' into no-dtt-in-unbounded-write 2023-11-10 12:57:42 +00:00
Jeroen Ketema
617d950a25 Apply suggestions from code review
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2023-11-10 13:55:39 +01:00
Tamás Vajk
340b20f93d Merge pull request #14743 from tamasvajk/standalone/adjust-nuget-test
C#: Adjust standalone integration test to not reference mono assemblies
2023-11-10 13:43:54 +01:00
Tom Hvitved
9f0b0733a6 Merge pull request #14589 from hvitved/csharp/fqn-backticks
C#: Use `C'X` fully-qualified-name format instead of `C<,...,>`
2023-11-10 13:33:36 +01:00
Jeroen Ketema
1c87875049 C++: Drop the size return value of strlcat from hasTaintFlow 2023-11-10 13:15:57 +01:00
Jeroen Ketema
5e21a5d284 C++: Fix flow for return values of strlcat and strlcpy 2023-11-10 12:28:48 +01:00
Jeroen Ketema
ba51b65d84 C++: Fix hasRemoteFlowSource for fgets
Also add the test that exposed this. Note that the test would only have started
failing after `cpp/uncontrolled-process-operation` with the rewrite of the
query away from default taint tracking, which has not happened yet.
2023-11-10 11:56:23 +01:00
Tamas Vajk
334fb1fc95 C#: Adjust standalone integration test to not reference mono assemblies 2023-11-10 11:47:28 +01:00
Alex Denisov
0fb439b54d Swift: test ElementArchetypeType via PackType 2023-11-10 11:44:45 +01:00
Alex Denisov
e865c3cbd3 Swift: extract parameter packs 2023-11-10 10:20:14 +01:00
Jeroen Ketema
e4c8406365 C++: Split strlcat off in a separate model 2023-11-10 10:11:57 +01:00
Tony Torralba
1f0d9e50c5 Merge pull request #14739 from github/workflow/coverage/update
Update CSV framework coverage reports
2023-11-10 09:25:02 +01:00
Tom Hvitved
ae3d98fd6f C#: Add change note 2023-11-10 08:57:13 +01:00
Tom Hvitved
57ec0948cf C#: Update expected test output 2023-11-10 08:46:15 +01:00
Tom Hvitved
2971a20760 C#: Update MaD rows 2023-11-10 08:46:15 +01:00
Tom Hvitved
b72f34591d C#: Use {get,has}FullyQualifiedName throughout 2023-11-10 08:46:15 +01:00
Tom Hvitved
66dc5501e8 C#: Deprecate {get,has}QualifiedName and replace with {get,has}FullyQualifiedName 2023-11-10 08:46:01 +01:00
Paolo Tranquilli
b611e7cebf Merge pull request #14715 from github/redsun82/gen-file-docs
Swift: add more doc strings to generated things
2023-11-10 07:41:41 +01:00
github-actions[bot]
01a1b4aa50 Add changed framework coverage reports 2023-11-10 00:15:57 +00:00
Maiky
2d387a98ce Add go.mod 2023-11-10 01:00:01 +01:00
Maiky
78a65a7787 Remove import 2023-11-09 23:35:33 +01:00
Maiky
6d7598115e Undo changes in modules 2023-11-09 23:26:38 +01:00
Maiky
a7264c2b5c Requested Changes 2023-11-09 23:17:45 +01:00
Maiky
dc265e7542 Requested Changes 2023-11-09 23:17:15 +01:00
Mathias Vorreiter Pedersen
b858a284c9 Merge pull request #14726 from microsoft/28-strsafe-library-updates2 2023-11-09 21:39:10 +00:00
Cornelius Riemenschneider
246c169540 Merge pull request #14738 from github/criemen/fix-path
Take our node, not the one that comes first on the PATH.
2023-11-09 22:20:44 +01:00
Cornelius Riemenschneider
97fd2033f1 Take our node, not the one that comes first on the PATH. 2023-11-09 22:00:00 +01:00
Mathias Vorreiter Pedersen
39b9d2ea83 C++: Accept test changes. 2023-11-09 20:28:55 +00:00
Mathias Vorreiter Pedersen
eb1024c79b C++: Improve (and simplify) 'toString's. 2023-11-09 20:27:23 +00:00
Mathias Vorreiter Pedersen
86e791980c C++: Simplify 'isGlobalUse' and 'isGlobalDefImpl'. 2023-11-09 20:27:23 +00:00
Mathias Vorreiter Pedersen
9762313500 C++: Implement jumpStep using the indirection instead of index. 2023-11-09 20:27:23 +00:00
Mathias Vorreiter Pedersen
95bb70f577 C++: Also add a 'getIndirection' on 'GlobalDef' as well. This will be useful in the next commit. 2023-11-09 20:25:29 +00:00
Benjamin Rodes
5e140021fb Removed non-ascii characters. 2023-11-09 15:24:58 -05:00
Mathias Vorreiter Pedersen
fd26ae18bf C++: Obtain the SSA variable of a 'GlobalUse' using the indirection instead of the index (like we do for non-global uses as well). 2023-11-09 20:20:27 +00:00
Mathias Vorreiter Pedersen
bb5a78d3f1 C++: Factor the IPA body of 'TGlobalUse' and 'TGlobalDef' out into predicates. 2023-11-09 20:17:47 +00:00
Tamás Vajk
7112409d27 Merge pull request #14723 from tamasvajk/standalone/include-nuget-restored-folders
C#: Include all (legacy) nuget restored folders in standalone references
2023-11-09 20:27:44 +01:00
Anders Schack-Mulligen
657c29f409 Java/C++: Share valueFlowStep. 2023-11-09 20:24:28 +01:00
Tom Hvitved
94d08aa443 Merge pull request #14662 from hvitved/csharp/mad-generics
C#: Include type parameters in MaD format for generics
2023-11-09 19:46:01 +01:00
Benjamin Rodes
8674139de6 Change log file name change 2023-11-09 13:24:14 -05:00
Geoffrey White
ebf7231be7 Swift: Make the 'completePath' models work. 2023-11-09 18:21:12 +00:00
Geoffrey White
9b5556e245 Swift: Test 'completePath' more carefully. 2023-11-09 18:21:12 +00:00
Geoffrey White
2d313ef4c7 Swift: Add some path injection sink models. 2023-11-09 18:21:12 +00:00
Mathias Vorreiter Pedersen
0963af2ee7 C++: Add failing tests. 2023-11-09 18:01:22 +00:00
Jeroen Ketema
a051a57e00 Update cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2023-11-09 17:48:45 +01:00
Jeroen Ketema
0b91310357 C++: Add models for strlcpy and strlcat 2023-11-09 17:21:37 +01:00
Anders Schack-Mulligen
b8e7e1d15e Java/C++: Share ssaUpdateStep. 2023-11-09 16:02:44 +01:00
Anders Schack-Mulligen
daffae020b Java/C++: Share eqFlowCond. 2023-11-09 16:00:46 +01:00
Anders Schack-Mulligen
cad003a39e Merge pull request #14732 from aschackmull/cpp/range-ssa
C++: Fix operand ssa variables for range analysis.
2023-11-09 15:17:47 +01:00
Chris Smowton
c060827a5d Merge pull request #14699 from smowton/smowton/feature/jdk21-sequenced-collections-models
Java: model JDK21 SequencedCollection, Set and Map
2023-11-09 14:15:08 +00:00
Mathias Vorreiter Pedersen
7048190929 Update cpp/ql/src/Security/CWE/CWE-120/UnboundedWrite.ql
Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com>
2023-11-09 12:39:10 +00:00
Owen Mansel-Chan
e16647fc87 Merge pull request #14731 from owen-mc/docs/dataflow-never-skip
Docs: document dataflow `neverSkip` (and expand section on hidden nodes)
2023-11-09 12:08:00 +00:00
Michael Nebel
4cc75c5bd6 Merge pull request #14564 from michaelnebel/csharp/cildefaultfalse
C#: Disable CIL extraction by default.
2023-11-09 13:06:54 +01:00
Owen Mansel-Chan
38766c497a Document neverSkip to show nodes in paths 2023-11-09 11:59:04 +00:00
Geoffrey White
cd147038cd Swift: Fill some gaps in the URL, NSURL models. 2023-11-09 11:51:18 +00:00
Geoffrey White
a86862d578 Swift: Add test cases (heuristic). 2023-11-09 11:33:10 +00:00
Geoffrey White
04016ebd20 Swift: Add test cases (more library functions). 2023-11-09 11:31:58 +00:00
Geoffrey White
f99df55e94 Swift: Add test stubs. 2023-11-09 11:28:33 +00:00
Anders Schack-Mulligen
abe0bb70ac C++: Fix operand ssa variables for range analysis. 2023-11-09 12:26:53 +01:00
Paolo Tranquilli
331fbf3251 Merge branch 'main' into redsun82/gen-file-docs 2023-11-09 12:14:10 +01:00
Paolo Tranquilli
dcb2117b31 Swift: tweak generated doc comments 2023-11-09 12:12:07 +01:00
Owen Mansel-Chan
5eaf682b77 Expand documentation of hidden nodes 2023-11-09 10:37:21 +00:00
Tom Hvitved
f58ff6ac6f C#: Manually update two more MaD rows 2023-11-09 11:25:09 +01:00
Anders Schack-Mulligen
ff6b8c4eb1 Merge pull request #14721 from aschackmull/shared/ssareadpos-share
Java/C++/RangeAnalysis: Move SsaReadPosition to shared qlpack.
2023-11-09 11:22:20 +01:00
Tamas Vajk
5c05a4c752 Restore nuget.exe and dotnet restore packages to separate folders 2023-11-09 11:20:00 +01:00
Cornelius Riemenschneider
3dcb039c76 Merge branch 'main' into criemen/java-int-tests 2023-11-09 11:19:04 +01:00
Tamas Vajk
d44d980003 C#: Exclude tools folders in legacy nuget packages 2023-11-09 11:19:02 +01:00
Cornelius Riemenschneider
cfa47a6d8e Merge pull request #14677 from github/criemen/js-bazel
JS: Move the language pack build and tests to Bazel
2023-11-09 11:15:42 +01:00
Chris Smowton
db045e0d9e Merge pull request #14729 from github/dependabot/go_modules/go/extractor/extractor-dependencies-479a80dd5e
Bump the extractor-dependencies group in /go/extractor with 1 update
2023-11-09 09:40:13 +00:00
Tamas Vajk
fd99e1f6a5 C#: Add test case with nuget package containing tools 2023-11-09 10:33:34 +01:00
Cornelius Riemenschneider
b4ec13235d Address review. 2023-11-09 09:40:29 +01:00
Tom Hvitved
5ae025f39a C#: Add change note 2023-11-09 08:45:25 +01:00
Tom Hvitved
76e6f81075 C#: Allow for explicit interface names in MaD consistency check 2023-11-09 08:34:36 +01:00
Tom Hvitved
136adb2df2 C#: Regenerate dotnet/runtime models 2023-11-09 08:34:36 +01:00
Tom Hvitved
f920bc164a C#: Update model generator to output one file per namespace 2023-11-09 08:34:36 +01:00
Tom Hvitved
7aed6f9233 C#: Manually update some MaD rows 2023-11-09 08:34:36 +01:00
Tom Hvitved
11c113bbd5 C#: Use new format for generics when parsing MaD rows 2023-11-09 08:34:36 +01:00
Tom Hvitved
84773fcde4 C#: Convert existing models using model converter 2023-11-09 08:34:35 +01:00
Tom Hvitved
74f483a6f5 C#: Update model conversion queries 2023-11-09 08:34:35 +01:00
Tom Hvitved
6f4311d656 C#: Include type parameters when printing MaD rows with generics 2023-11-09 08:34:06 +01:00
dependabot[bot]
8a3f29a6bf Bump the extractor-dependencies group in /go/extractor with 1 update
Bumps the extractor-dependencies group in /go/extractor with 1 update: [golang.org/x/tools](https://github.com/golang/tools).

- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.14.0...v0.15.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>
2023-11-09 03:49:54 +00:00
Ben Rodes
79dcb4b48c Update cpp/ql/lib/change-notes/2023-11-8-strsafe-models.md
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2023-11-08 12:37:55 -05:00
Benjamin Rodes
bdae2af0e2 Adding missing strsafe sprintf variants. 2023-11-08 12:20:53 -05:00
Benjamin Rodes
c3ff181198 Adding change log 2023-11-08 12:20:04 -05:00
Mathias Vorreiter Pedersen
68e7f84c23 Merge pull request #14661 from geoffw0/commandinject4
Swift: Fix defaultImplicitTaintRead on fields
2023-11-08 15:52:18 +00:00
Geoffrey White
6b434d10ce Merge pull request #14701 from geoffw0/promotecmdline
Swift: Promote the command injection query out of experimental
2023-11-08 15:46:29 +00:00
Paolo Tranquilli
e68826bf99 Merge pull request #14261 from github/alexdenisov/upgrade-to-swift-5.9
Swift: upgrade to 5.9
2023-11-08 16:15:41 +01:00
Cornelius Riemenschneider
6b37d2009b Merge branch 'main' into criemen/js-bazel 2023-11-08 16:11:47 +01:00
Mathias Vorreiter Pedersen
38bd893c81 Merge branch 'main' into no-dtt-in-unbounded-write 2023-11-08 15:06:59 +00:00
Mathias Vorreiter Pedersen
e90803a81c C++: Rewrite 'cpp/unbounded-write' away from DefaultTaintTracking. 2023-11-08 14:57:04 +00:00
Cornelius Riemenschneider
512c6a59c5 Merge pull request #14718 from github/criemen/go-ub
Restructure go Makefile: Build the per-platform target.
2023-11-08 15:30:57 +01:00
Mathias Vorreiter Pedersen
d8e75e66d7 Merge pull request #14717 from github/alexdenisov/fix-cfg-for-single-value-stmt-expr
Swlft: fix CFG for SingleValueStmtExpr
2023-11-08 14:26:00 +00:00
Rasmus Wriedt Larsen
9b0ad8295e Python: Add test of nested classes 2023-11-08 14:58:40 +01:00
Shati Patel
3586231e7d Merge pull request #14668 from github/shati-patel/docs-databases
VS Code extension docs: Changes to database downloads
2023-11-08 13:55:43 +00:00
Rasmus Wriedt Larsen
9d5cf0b331 Merge branch 'main' into class-attribute-flow 2023-11-08 14:30:53 +01:00
Rasmus Wriedt Larsen
6d4e000c7c Merge pull request #14590 from RasmusWL/fix-dataflow-class-scope
Python: Fix dataflow consistency error due to missing class scope
2023-11-08 14:30:34 +01:00
Rasmus Wriedt Larsen
43d9d2ceb7 Merge pull request #14603 from github/max-schaefer/broken-crypto-algorithm-link
JavaScript/Python/Ruby: Improve alert message for `*/weak-cryptographic-algorithm`.
2023-11-08 14:29:24 +01:00
Anders Schack-Mulligen
f9132c5ff0 Java: Duplicate a bit more code to postpone Java-C# cleanup. 2023-11-08 14:04:34 +01:00
Tamas Vajk
2273bb13b8 C#: Include all (legacy) nuget restored folders in standalone references 2023-11-08 14:02:41 +01:00
Tamas Vajk
b782e5bf44 C#: Add test case with legacy nuget restore 2023-11-08 14:01:10 +01:00
Tamás Vajk
4ae35d179e Merge pull request #14707 from tamasvajk/standalone/framework-nuget-1
C#: Keep only one framework reference nuget package in standalone
2023-11-08 12:52:52 +01:00
Alex Denisov
d510739ca2 Swift: add 5.9 chagenote 2023-11-08 12:20:33 +01:00
Anders Schack-Mulligen
1f4cd74a1c Java/C++: Move SsaReadPosition to shared qlpack. 2023-11-08 12:11:17 +01:00
Michael Nebel
795e32c681 Merge pull request #14693 from michaelnebel/csharp/fixcompilerwarning
C#: Fix compiler warning of possible null de-reference.
2023-11-08 12:04:41 +01:00
Michael Nebel
b1c3915fd9 Merge pull request #14712 from michaelnebel/csharp/tracerdotnettest
C#: Tracer improvement for `dotnet test`
2023-11-08 12:03:19 +01:00
Geoffrey White
d78a7b9d94 Swift: Add credit to change note. 2023-11-08 10:46:57 +00:00
Michael Nebel
0cf00ebb5d C#: Re-introduce null check in cached entity hash code calculation. 2023-11-08 10:59:06 +01:00
Cornelius Riemenschneider
f12310cb86 The java-version-too-old relies on a Java 8 installation.
We don't have a Java 8 build on the M1 machines, therefore skip this test.
2023-11-08 10:36:47 +01:00
Cornelius Riemenschneider
137403f649 Java: Move more tests to use the try_use_java11() helper.
This is in preparation of executing these tests on GH-hosted M1 runners,
where we need to have architecture-specific path handling.
It's nicer to fix all of this in one place (the helper), than to run around
fixing individual tests.
2023-11-08 10:33:50 +01:00
Mathias Vorreiter Pedersen
ab64d9a9d6 Merge pull request #14713 from MathiasVP/no-gvn-as-ssa-in-range-analysis
C++: Don't use GVN as SSAVariable in new range analysis
2023-11-08 09:28:15 +00:00
Michael Nebel
69e8621062 C#: Fix compiler warning of possible null de-reference. 2023-11-08 10:21:26 +01:00
Paolo Tranquilli
ac838d72de Codegen: mark all generated files and classes as INTERNAL 2023-11-08 10:02:17 +01:00
Paolo Tranquilli
b7543f5dc7 Codegen: pass ql_internal to Stub 2023-11-08 09:54:21 +01:00
Michael Nebel
cd4a546763 C#: Add CIL extraction change note. 2023-11-08 09:40:01 +01:00
Michael Nebel
8f23ba83be C#: Update Options unit tests to reflect the new default. 2023-11-08 09:40:01 +01:00
Michael Nebel
9b56e83745 C#: Set CIL extraction default to false. 2023-11-08 09:40:01 +01:00
Tony Torralba
5442cdb49c Merge pull request #14610 from atorralba/atorralba/java/jms-deserialization
Java: Add JMS sink to java/unsafe-deserialization
2023-11-08 09:10:20 +01:00
Erik Krogh Kristensen
f643fd7d74 Merge pull request #14716 from erik-krogh/invalid-main
JS: catch when the main: path is invalid on Windows
2023-11-08 08:33:58 +01:00
Anders Schack-Mulligen
45ae4ed362 Merge pull request #14711 from aschackmull/shared/rangeutil-share2
Java/C++/RangeAnalysis: Move a couple of utility predicates to shared qlpack
2023-11-08 08:33:12 +01:00
Mathias Vorreiter Pedersen
a8eed6bd7e Merge pull request #14704 from MathiasVP/fix-uninitialized-local
C++: IR'ify `cpp/uninitialized-local` and fix FPs
2023-11-07 22:45:34 +00:00
Cornelius Riemenschneider
3f95dd6916 Restructure go Makefile: Build the per-platform target.
This changes the default build target we use to build the go extractor
to use th per-platform targets (requires internal change to follow up).
This also builds the macos target as universal binary.
2023-11-07 20:21:10 +01:00
Geoffrey White
b63294764b Merge pull request #14705 from geoffw0/qhelplink
Fix a dead ReDoS link in docs
2023-11-07 17:40:19 +00:00
Mathias Vorreiter Pedersen
69502d0c31 C++: Add some more tests. 2023-11-07 17:31:01 +00:00
Alex Denisov
12f9e3a1dd Swlft: fix CFG for SingleValueStmtExpr 2023-11-07 18:12:39 +01:00
erik-krogh
ae577d1e44 catch when the main: path is invalid on Windows 2023-11-07 17:42:21 +01:00
Alex Denisov
dd20a9b009 Swlft: fix wording in the comment 2023-11-07 17:28:37 +01:00
Alex Denisov
df256e601a Swlft: add explicit SingleValueStmtExpr test 2023-11-07 17:26:44 +01:00
Mathias Vorreiter Pedersen
5a9867c5b0 Merge pull request #14714 from MathiasVP/geoffw0-follow-up-comment
C++: Add comment to testcase
2023-11-07 15:33:15 +00:00
Paolo Tranquilli
10afa4381a Swift: add more doc strings to generated things 2023-11-07 16:29:03 +01:00
Mathias Vorreiter Pedersen
1c8f474848 C++: Add comment as suggested in the PR review for #14708. 2023-11-07 15:16:38 +00:00
Mathias Vorreiter Pedersen
2787f0a0fc Merge pull request #14708 from MathiasVP/add-testcase-for-range-analysis
C++: Add range analysis testcase
2023-11-07 15:15:45 +00:00
Mathias Vorreiter Pedersen
2d43eec3c3 C++: Accept test changes. 2023-11-07 14:57:30 +00:00
Mathias Vorreiter Pedersen
91b29eee53 C++: Don't use GVN as an SSAVariable in range analysis. 2023-11-07 14:52:50 +00:00
Mathias Vorreiter Pedersen
a04830b8b2 Merge pull request #14697 from MathiasVP/range-analysis-simplify-conversions
C++: Simplify the definition of `SemExpr` for range analysis
2023-11-07 14:52:09 +00:00
Rasmus Wriedt Larsen
5433907c33 Python: Accept more test changes
All are for the better 🎉
2023-11-07 15:49:14 +01:00
Michael Nebel
21cb4909cf C#: Add integration test. 2023-11-07 15:26:55 +01:00
Anders Schack-Mulligen
12cba7909b Java/C++: Move range util guard-controls predicates to shared pack. 2023-11-07 15:14:34 +01:00
Anders Schack-Mulligen
f2ca52d951 Java/C++: Move range util backEdge predicate to shared pack. 2023-11-07 15:14:34 +01:00
Tom Hvitved
b2512eb212 Merge pull request #14678 from hvitved/csharp/mad-operator-fix
C#: Correctly parse operator names in MaD
2023-11-07 15:11:01 +01:00
Rasmus Wriedt Larsen
dc8ca70ab5 Merge pull request #14694 from RasmusWL/python-validtest-success
Python: Misc: show that all tests passed in validTest
2023-11-07 14:56:57 +01:00
Michael Nebel
7ea8f88d47 C#: Allow exe and dll files for dotnet test to start with any character. 2023-11-07 14:52:37 +01:00
Cornelius Riemenschneider
9c8e2321be Merge branch 'main' into criemen/js-bazel 2023-11-07 14:36:45 +01:00
Cornelius Riemenschneider
697a7b8a60 Merge pull request #14702 from github/criemen/java-int-test
Java: Make integration test more robust wrt recent Java versions.
2023-11-07 14:00:40 +01:00
Alex Denisov
2b7ce23653 Swlft: add database upgrade scripts 2023-11-07 13:40:42 +01:00
Alex Denisov
33de177fea Swift: extract SingleValueStmtExpr 2023-11-07 13:40:35 +01:00
Alex Denisov
bbde709b3f Swift: upgrade to 5.9.1 2023-11-07 13:40:28 +01:00
Tamas Vajk
a70d9691da C#: Add standalone test with multiple targets 2023-11-07 13:39:43 +01:00
Tom Hvitved
af7b295c59 Address review comments 2023-11-07 13:01:19 +01:00
Mathias Vorreiter Pedersen
9dca6697fb C++: Add a testcase that fails to terminate in modulus analysis when we don't have IR operands as SSA variables. 2023-11-07 11:52:35 +00:00
Tamas Vajk
0f31fc7cbe C#: Keep only one framework reference nuget package in standalone 2023-11-07 12:12:59 +01:00
Rasmus Wriedt Larsen
5220a8d3f8 Update python/ql/test/experimental/dataflow/validTest.py
Co-authored-by: Taus <tausbn@github.com>
2023-11-07 11:30:13 +01:00
Rasmus Wriedt Larsen
9f43108ba8 Python: Fix DataFlowCall.getEnclosingCallable
Now it is aligned with the implementation of DataFlow::Node

See 4bc4e0845d/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll (L134-L138)
2023-11-07 11:29:23 +01:00
Rasmus Wriedt Larsen
904a8b1ea9 Python: Add consistency tests for class scope 2023-11-07 11:29:23 +01:00
Rasmus Wriedt Larsen
5bee44dcfe Python: add change-note 2023-11-07 11:27:11 +01:00
Rasmus Wriedt Larsen
6568332e3d Python: Add basic flow for class attributes 2023-11-07 11:23:42 +01:00
Rasmus Wriedt Larsen
6c50c2bfe6 Python: Highlight missing flow for class attributes 2023-11-07 11:23:42 +01:00
Cornelius Riemenschneider
ccaa792343 Address on-slack review. 2023-11-07 11:07:37 +01:00
Mathias Vorreiter Pedersen
6669cf805f C++: Add change note. 2023-11-07 09:32:07 +00:00
Mathias Vorreiter Pedersen
0fd4d4a114 C++: Add QLDoc. 2023-11-07 09:29:34 +00:00
Geoffrey White
e8a466a02c Update dead link. 2023-11-07 09:26:07 +00:00
Mathias Vorreiter Pedersen
022c9eb3cd C++: Add a barrier feature to 'MustFlow'. 2023-11-07 09:23:42 +00:00
Mathias Vorreiter Pedersen
6bf2d47321 C++: Allow source = sink in 'MustFlow'. 2023-11-07 09:23:42 +00:00
Mathias Vorreiter Pedersen
1dc08941f8 C++: Use 'MustFlow' in 'cpp/uninitialized-local'. 2023-11-07 09:23:41 +00:00
AlexDenisov
a0e73eaab0 Merge pull request #14696 from github/alexdenisov/force-canonical-types
Swlft: force canonical type computation before using the type
2023-11-07 10:23:16 +01:00
Mathias Vorreiter Pedersen
a17cd9bc1c Merge pull request #14667 from MathiasVP/more-function-input-and-output-ipa-numbers
C++: Allocate more `FunctionInput` and `FunctionOutput`s
2023-11-07 08:57:31 +00:00
Geoffrey White
4ce8d953d2 Merge pull request #14698 from geoffw0/realmswift
Swift: Fix an issue with Realm sinks for swift/cleartext-storage-database
2023-11-07 08:37:27 +00:00
Cornelius Riemenschneider
cff9bcfabc Revert "Revert "Java: Make integration test more robust wrt recent Java versions.""
This reverts commit 4e70e674fd.
2023-11-06 23:29:33 +01:00
Cornelius Riemenschneider
4e70e674fd Revert "Java: Make integration test more robust wrt recent Java versions."
This reverts commit ae21bbf0b2.
2023-11-06 23:26:21 +01:00
Cornelius Riemenschneider
ae21bbf0b2 Java: Make integration test more robust wrt recent Java versions.
I've been investigating moving the Java integration tests to a
GH-hosted macos runner, instead of a self-hosted one.
This test is not compatible with a GH-hosted runners Java setup.
It is also not compatible to being exposed to JAVA_21_HOME_X64 variable yet.

This PR fixes both issues.
2023-11-06 23:22:05 +01:00
Geoffrey White
3465c34cb6 Merge pull request #14680 from geoffw0/dataclosure
Swift: Generalize flow through subscript writes / test and fix some closure methods of Data
2023-11-06 19:39:08 +00:00
amammad
e8eff78799 fix tests because of error in Frameworks.qll 2023-11-06 19:19:36 +01:00
amammad
ad756d59c8 put new frameworks in Frameworks.qll and fix some mistakes of Baize 2023-11-06 19:17:50 +01:00
amammad
315bdc2b48 add tests for new frameworks 2023-11-06 19:13:57 +01:00
amammad
637c52d10a separate each new FileSystemAccess packages. 2023-11-06 19:03:55 +01:00
Geoffrey White
c85bdcd5ab Swift: Change note. 2023-11-06 17:36:58 +00:00
Mathias Vorreiter Pedersen
4455ed982d C++: Accept query test changes. 2023-11-06 17:33:46 +00:00
Geoffrey White
1c6a4b8cbf Swift: Update the test .qlref. 2023-11-06 17:32:25 +00:00
Mathias Vorreiter Pedersen
84594e66bc Merge pull request #14682 from geoffw0/filepathclosure
Swift: Correct a couple of FilePath models.
2023-11-06 17:31:17 +00:00
Geoffrey White
127f819762 Swift: Move command injection query out from experimental. 2023-11-06 17:23:28 +00:00
Ian Lynagh
e0c89a700f Merge pull request #14695 from igfoo/igfoo/order
Docs: Put lists in supported-frameworks.rst in more alphabetical order
2023-11-06 17:00:39 +00:00
Cornelius Riemenschneider
be02512dfe Add a build system for the junit tests.
This is a bit more complicated than our usual setup, as we both need to
unzip the typescript parser wrapper, and make node accessible on the path.
2023-11-06 17:58:28 +01:00
Chris Smowton
24b4b05be8 Add models for new Collections methods 2023-11-06 16:44:40 +00:00
Chris Smowton
d30d71e048 Add change note 2023-11-06 16:38:44 +00:00
Geoffrey White
426bdc0011 Swift: Add test cases. Before the changes, we don't catch the cases for return values from the closures. 2023-11-06 16:32:23 +00:00
Mathias Vorreiter Pedersen
d38fa13299 C++: Remove more uses of 'getConverted' and 'getUnconverted'. 2023-11-06 16:11:55 +00:00
Chris Smowton
5b72aee3ae Java: model JDK21 SequencedCollection, Set and Map 2023-11-06 16:04:13 +00:00
Mathias Vorreiter Pedersen
e91987b1a9 C++: Accept test changes. 2023-11-06 16:02:06 +00:00
Mathias Vorreiter Pedersen
d544f47746 C++: Simplify the definition of 'SemExpr' by instead making non-overflowing conversions copy value expressions. 2023-11-06 16:01:59 +00:00
Geoffrey White
e4f6b1ac27 Swift: Change note. 2023-11-06 16:00:22 +00:00
Geoffrey White
77e48f72ec Swift: Detect Realm sinks more reliably. 2023-11-06 15:54:17 +00:00
Geoffrey White
9ec5e6e35e Swift: Re-organize the RealmStore constructor. 2023-11-06 15:54:17 +00:00
Geoffrey White
424046d238 Swift: Add test case. 2023-11-06 15:54:17 +00:00
Alex Denisov
80c4b7357a Swlft: force canonical type computation before using the type
`getCanonicalType` will force computation of the canonical type.
Without canonical type computed. `getString` may cause crashes in
certain cases.
2023-11-06 16:53:38 +01:00
Mathias Vorreiter Pedersen
31c2a3be98 C++: Don't redefine the meaning of the single-parameter 'isParameterDeref' and accept test changes. 2023-11-06 15:52:58 +00:00
Ian Lynagh
decbaa9dc7 Docs: Put lists in supported-frameworks.rst in more alphabetical order
They were almost alphabetical, but not quite.

Python was ordered by category first, and by name within each catogory.
I've left it like that, but it would probably be better to be
consistent between languages, one way or the other.
2023-11-06 15:49:16 +00:00
Michael Nebel
3f0be47c7b Merge pull request #14655 from michaelnebel/csharp/projectassetspackages
C#: Use `project.assets.json` for package dependencies.
2023-11-06 16:26:38 +01:00
Robert Marsh
49428c4585 Merge pull request #14683 from geoffw0/nsstringclosure
Swift: Model NSString.enumerate*
2023-11-06 10:19:25 -05:00
Rasmus Wriedt Larsen
43f1d092f1 Python: Misc: show that all tests passed in validTest 2023-11-06 16:04:58 +01:00
Tom Hvitved
d86293f9b4 Merge pull request #14690 from hvitved/csharp/gvn-unbound-type 2023-11-06 15:30:53 +01:00
Mathias Vorreiter Pedersen
ff30308a2b C++: Only the first indirection of the argument should be the remote flow sink. 2023-11-06 13:57:14 +00:00
Tom Hvitved
4b9430d59e Merge pull request #14688 from hvitved/csharp/deprecate-get-instance-type
C#: Deprecate `UnboundGenericType::getInstanceType/0`
2023-11-06 14:32:54 +01:00
Mathias Vorreiter Pedersen
cd2eec0aa0 C++: Also override the single-parameter 'isParameterDeref' in 'InParameterDeref'. 2023-11-06 13:23:31 +00:00
Cornelius Riemenschneider
52fcc5f435 Export test data directories. 2023-11-06 13:47:56 +01:00
Cornelius Riemenschneider
63854e36b4 Use the TestPaths helper to lookup files. 2023-11-06 13:47:56 +01:00
Cornelius Riemenschneider
a773532d07 Refactor JS test suite to be more in line with other Java projects.
Therefore, we move the test suite out of the `src` directory.
2023-11-06 13:47:56 +01:00
Cornelius Riemenschneider
6c7ea86a12 Introduce a bazel-based build for the entire JS pack. 2023-11-06 13:47:56 +01:00
Cornelius Riemenschneider
465eb00228 More fine-grained dependency on internal extractors. 2023-11-06 13:44:28 +01:00
Rasmus Wriedt Larsen
f6ae7523b5 Merge pull request #14591 from RasmusWL/minor-stringpool-improvement
Python: Minor cleanup for string pool interaction
2023-11-06 13:13:27 +01:00
Tom Hvitved
12cd1c1011 C#: Deprecate UnboundGenericType::getInstanceType/0 2023-11-06 13:01:57 +01:00
Geoffrey White
4e214e1c7c Merge pull request #14691 from geoffw0/webview2
Swift: Add a webview test case
2023-11-06 11:08:09 +00:00
shati-patel
68da5e2bbe Fix some names + a spurious quotation mark 2023-11-06 10:56:03 +00:00
Rasmus Wriedt Larsen
92b13c4259 Merge branch 'main' into amammad-python-FileSystemAccess 2023-11-06 11:30:09 +01:00
Rasmus Wriedt Larsen
3d8a7e0ee3 Python: Add change-note 2023-11-06 11:29:52 +01:00
Chris Smowton
c6193ebc0c Merge pull request #14687 from github/dependabot/go_modules/go/extractor/extractor-dependencies-a562808574
Bump the extractor-dependencies group in /go/extractor with 1 update
2023-11-06 10:05:44 +00:00
Geoffrey White
838a00bbc9 Swift: Add a webview test case from a branch that didn't make it. 2023-11-06 09:44:53 +00:00
Erik Krogh Kristensen
2abdf7dbbd Merge pull request #14686 from erik-krogh/delete-yarn
JS: remove the remaining yarn files
2023-11-06 10:37:06 +01:00
Tom Hvitved
602d16d73f C#: Add another data flow test 2023-11-06 10:18:32 +01:00
Geoffrey White
b99e44c3ca Swift: Fix the Data test. 2023-11-06 09:18:27 +00:00
Michael Nebel
4bcf9e50a0 C#: Address review comments. 2023-11-06 10:02:53 +01:00
Tom Hvitved
467854ba4b C#: Convert a data flow test to use inline test expectations 2023-11-06 09:54:34 +01:00
Kevin Stubbings
57c645bd24 Added support for same struct and added new test 2023-11-05 22:34:35 -08:00
dependabot[bot]
2d9ff85753 Bump the extractor-dependencies group in /go/extractor with 1 update
Bumps the extractor-dependencies group in /go/extractor with 1 update: [golang.org/x/mod](https://github.com/golang/mod).

- [Commits](https://github.com/golang/mod/compare/v0.13.0...v0.14.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-11-06 03:19:42 +00:00
Kevin Stubbings
1f2e8d898d Address Feedback 2023-11-05 14:28:34 -08:00
Tom Hvitved
3e3ea51e69 C#: Correctly parse operator names in MaD 2023-11-05 20:58:47 +01:00
Tom Hvitved
2a33a86c9d C#: Merge ExternalFlow.qll and ExternalFlowExtensions.qll, and move to internal 2023-11-05 20:58:47 +01:00
Tom Hvitved
aa521ecd59 C#: Include more libraries in flow summaries test 2023-11-05 20:23:10 +01:00
erik-krogh
abcb5a7a95 remove the remaining yarn files 2023-11-05 19:24:59 +01:00
Geoffrey White
e621d208e4 Merge branch 'main' into nsstringclosure 2023-11-03 20:54:53 +00:00
Geoffrey White
55ec27f47f Merge branch 'main' into filepathclosure 2023-11-03 20:54:16 +00:00
Geoffrey White
e90b630c9b Merge branch 'main' into dataclosure 2023-11-03 20:50:20 +00:00
Geoffrey White
c6bc1a3f3a Merge pull request #14684 from geoffw0/testsfix
Swift: Fix failing tests
2023-11-03 19:24:03 +00:00
Geoffrey White
07eba4e3b1 Swift: Fix some failing tests, looks like this could be the result of some recently merged PRs interacting (positively!) 2023-11-03 17:08:05 +00:00
Geoffrey White
041dc19055 Swift: Change note. 2023-11-03 16:22:46 +00:00
Geoffrey White
989a546796 Swift: Model the NSString.enumerate* methods. 2023-11-03 16:22:45 +00:00
Geoffrey White
d0ca7045d4 Swift: Fix some NSString models. 2023-11-03 16:07:34 +00:00
Geoffrey White
a59ed5bc49 Swift: Add test cases. 2023-11-03 15:45:45 +00:00
Geoffrey White
06191922c3 Swift: Correct a couple of FilePath models. 2023-11-03 15:12:31 +00:00
Geoffrey White
71ad6a8262 Swift: Change note. 2023-11-03 14:53:37 +00:00
Geoffrey White
0d7943031c Swift: Generalize subscript assignment storeStep. 2023-11-03 14:53:37 +00:00
yoff
f969274a29 Merge pull request #14644 from yoff/python/filter-local-self-loops
Python: filter local self loops
2023-11-03 15:45:09 +01:00
Sam Browning
225c96ec9f Merge branch 'main' of https://github.com/github/codeql 2023-11-03 09:42:55 -04:00
Geoffrey White
245f475fdb Swift: Remove duplicate model. 2023-11-03 12:55:36 +00:00
Michael Nebel
df4f2a367b C#: Update unit tests. 2023-11-03 13:42:32 +01:00
Michael Nebel
31f602cd47 C#: Make path concatenation OS invariant. 2023-11-03 13:35:06 +01:00
Michael Nebel
4689bdb468 C#: Log unused downloaded packages. 2023-11-03 13:27:51 +01:00
Michael Nebel
1054e7a4ee C#: Update assets unit tests. 2023-11-03 13:27:51 +01:00
Michael Nebel
003166af13 C#: Collect information about used dependencies in a Dependencies object. 2023-11-03 13:27:51 +01:00
Geoffrey White
e7e6529df6 Swift: Add tests. 2023-11-03 12:21:32 +00:00
yoff
8d3ed68b68 Merge pull request #14653 from yoff/python/add-aws-to-supported-frameworks
Python: Add AWS Lambda as a supported framework
2023-11-03 13:14:30 +01:00
Geoffrey White
49add7d8ce Swift: Add stubs to test. 2023-11-03 12:07:15 +00:00
Michael Nebel
eb228b6e68 C#: Address some review comments. 2023-11-03 11:32:53 +01:00
Michael Nebel
62dd86bacb C#: Update standalone integration tests expected output. 2023-11-03 11:32:48 +01:00
Michael Nebel
7b91be6c52 C#: Allways add Windows Desktop App dlls if the NuGet package is downloaded. 2023-11-03 11:31:28 +01:00
Michael Nebel
11505d6842 C#: Make the assembly cache more robust against non-existing paths. 2023-11-03 11:31:27 +01:00
Michael Nebel
56a70da28f C#: Remove package cleanup in the dependency manager. 2023-11-03 11:31:27 +01:00
Michael Nebel
70996a4c7e C#: Rename dllDirNames to dllPaths. 2023-11-03 11:31:27 +01:00
Michael Nebel
576eda3ec6 C#: Add missing package directory to included dlls. 2023-11-03 11:31:27 +01:00
Michael Nebel
4cebb7e848 C#: Integrate the assets parsing and fetching in the dependency manager. 2023-11-03 11:31:27 +01:00
Michael Nebel
f8d427336e C#: Add assets parsing unit test. 2023-11-03 11:31:27 +01:00
Michael Nebel
7bbf1a24d4 C#: Add assets.json parser. 2023-11-03 11:31:27 +01:00
Michael Nebel
c6c00e7179 C#: Add tests cases for parsing dotnet restore output to find assets.json files. 2023-11-03 11:31:27 +01:00
Michael Nebel
3a7df994cb C#: The dependency manager should find assets.json files when doing a project or solution restore. 2023-11-03 11:31:27 +01:00
Michael Nebel
387a241efd C#: Set output verbosity to normal for both solution and project restore (needed to identify where assets file are located). 2023-11-03 11:31:27 +01:00
Paolo Tranquilli
506b911767 Merge pull request #14629 from github/redsun82/rework-resource-dir
Swift: rework resource dir
2023-11-03 11:14:49 +01:00
Michael Nebel
4009f03087 Merge pull request #14665 from michaelnebel/csharp/projectreference
C#: Update DependencyManager logic to exclude commented out references.
2023-11-03 10:30:03 +01:00
Tom Hvitved
9807a8e1d3 Merge pull request #14675 from hvitved/csharp/split-generated-mad-files-take2
C#: Split `generated/dotnet_runtime.yml` into separate files (take 2)
2023-11-03 10:24:38 +01:00
Tom Hvitved
af524f0043 Revert "C#: Temporary changes to model generator"
This reverts commit 0f6cea6bd6ecd61139dc09e7b68bf0b8ebc009fe.
2023-11-03 09:51:40 +01:00
Tom Hvitved
894f9ab8fa C#: Split generated/dotnet_runtime.yml into separate files 2023-11-03 09:51:40 +01:00
Tom Hvitved
7082efa037 C#: Temporary changes to model generator 2023-11-03 09:51:40 +01:00
Tom Hvitved
c34ad25cf9 Merge pull request #14674 from github/revert-14663-csharp/split-generated-mad-files
Revert "C#: Split `generated/dotnet_runtime.yml` into separate files"
2023-11-03 09:51:22 +01:00
Tom Hvitved
13e60d7b11 Revert "C#: Split generated/dotnet_runtime.yml into separate files" 2023-11-03 09:07:54 +01:00
Anders Schack-Mulligen
132cc03e3b Merge pull request #14664 from aschackmull/shared/modulus-step
RangeAnalysis: Improve bounds that rely on relative modulus.
2023-11-03 08:16:48 +01:00
Mathias Vorreiter Pedersen
679d64f0e8 Merge pull request #14647 from microsoft/24-odbc-model-instantiation-upstream2
C++: Adding a model implementation for ODBC.
2023-11-02 19:42:27 +00:00
Benjamin Rodes
30a512c96b Formatting 2023-11-02 15:01:15 -04:00
Robert Marsh
81d77bf37c Merge pull request #14578 from geoffw0/stringwith
Swift: Models for String methods involving closures.
2023-11-02 13:53:22 -04:00
Benjamin Rodes
947e0274c7 Adding sql injection test for ODBC. 2023-11-02 13:27:42 -04:00
shati-patel
ac0fd93cb3 Update docs for customizing settings 2023-11-02 17:17:02 +00:00
shati-patel
2f4eea5a0d Update docs for exploring ASTs 2023-11-02 17:16:47 +00:00
Benjamin Rodes
f404d7a5f8 Changes to address pr comments. 2023-11-02 13:11:23 -04:00
Mathias Vorreiter Pedersen
392b2af923 C++: Only the second indirection of the argument should be the remote flow source. 2023-11-02 16:51:24 +00:00
Mathias Vorreiter Pedersen
b82dfa9a21 C++: Fix failing test by allocating 'TFunctionInput's and 'TFunctionOutput's for more indirections. Note that we now mark two output nodes coming out of 'getaddrinfo' as a remote flow source (the first indirection and the second indirection). We'll fix that in the next commit. 2023-11-02 16:45:50 +00:00
Mathias Vorreiter Pedersen
5487b404ed C++: Add failing test. 2023-11-02 16:41:19 +00:00
Michael Nebel
0bf2d77a7e C#: Update integration tests. 2023-11-02 15:46:54 +01:00
Michael Nebel
a161d6e666 C#: Update unit tests. 2023-11-02 15:46:39 +01:00
Michael Nebel
9ea6ef06ef C#: Commented out references in project files should not be used. 2023-11-02 15:45:30 +01:00
Anders Schack-Mulligen
f2b52650d5 Rangeanalysis: Filter useless modulo results. 2023-11-02 15:29:56 +01:00
Tom Hvitved
a35bda2946 Merge pull request #14663 from hvitved/csharp/split-generated-mad-files
C#: Split `generated/dotnet_runtime.yml` into separate files
2023-11-02 14:36:48 +01:00
Tom Hvitved
f82f1df5d6 Merge pull request #14657 from hvitved/csharp/qualified-name
C#: Move qualified name computation into `QualifiedName.qll`
2023-11-02 14:36:13 +01:00
Anders Schack-Mulligen
7bf271fb6c RangeAnalysis: Improve bounds that rely on relative modulus. 2023-11-02 12:51:48 +01:00
Tom Hvitved
a9e2f55b61 C#: Split generated/dotnet_runtime.yml into separate files 2023-11-02 12:45:47 +01:00
Anders Schack-Mulligen
484d0fe4cd Merge pull request #14659 from aschackmull/shared/modulus-analysis
Java/C++: Share modulus analysis
2023-11-02 12:45:35 +01:00
Tom Hvitved
12d856737a Address review comments 2023-11-02 12:38:35 +01:00
Tony Torralba
8f4509f434 Merge pull request #14651 from github/workflow/coverage/update
Update CSV framework coverage reports
2023-11-02 10:48:32 +01:00
Geoffrey White
431d9d58f1 Merge pull request #14639 from geoffw0/anchorquery
Swift: New query for Missing Regular Expression Anchor
2023-11-02 09:20:19 +00:00
Geoffrey White
242399817a Swift: Remove 'only'. 2023-11-02 08:32:36 +00:00
yoff
fd757b0089 Update python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPrivate.qll
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2023-11-02 09:31:28 +01:00
Rasmus Lerchedahl Petersen
58bf70d61b Python: filter self steps from use-use flow
Factor out use-use flow in order to do this.
Also improve names and comments.

I also wanted to change the types in `difinitionFlowStep`, but
that broke the module instantiation.
2023-11-02 09:31:28 +01:00
Rasmus Lerchedahl Petersen
613831b2e1 Python: add test for post-update loop flow 2023-11-02 09:31:28 +01:00
Geoffrey White
c937230f1a Apply suggestions from code review
Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com>
2023-11-02 08:30:53 +00:00
yoff
c26c68c286 Merge pull request #14617 from yoff/python/module-for-import-time-flow
Python: module for import time flow
2023-11-02 09:28:51 +01:00
Anders Schack-Mulligen
7c3684dbb7 RangeAnalysis: Rename semExprModulus to exprModulus. 2023-11-02 08:19:23 +01:00
Anders Schack-Mulligen
400910e4d3 C++: Fix modulus analysis test. 2023-11-02 08:19:23 +01:00
github-actions[bot]
155073c498 Add changed framework coverage reports 2023-11-02 00:16:04 +00:00
Geoffrey White
48c3db2290 Swift: Change note. 2023-11-01 18:49:45 +00:00
Geoffrey White
206acea41c Swift: Fix defaultImplicitTaintRead for sinks that are field accesses on a subclass of the type containing the field. 2023-11-01 17:49:25 +00:00
Geoffrey White
727a7e804c Update swift/ql/src/queries/Security/CWE-020/MissingRegexAnchor.qhelp
Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com>
2023-11-01 16:32:25 +00:00
Sam Browning
37361d9f79 Merge branch 'main' of https://github.com/github/codeql 2023-11-01 11:43:33 -04:00
Anders Schack-Mulligen
f8ab64dff0 Java: Switch to shared modulus analysis. 2023-11-01 16:34:28 +01:00
Tom Hvitved
c717e346fb C#: Move qualified name computation into QualifiedName.qll 2023-11-01 16:21:55 +01:00
Anders Schack-Mulligen
ac115e0a6f Rangeanalysis: Reshuffle perf fix. This should result in the same join-order, but with less materialisation. 2023-11-01 15:59:24 +01:00
Anders Schack-Mulligen
bb2bbd2d4d Rangeanalysis: Remove useless pragma. 2023-11-01 15:59:24 +01:00
Anders Schack-Mulligen
f6794fe859 Rangeanalysis: Adjust modulo analysis comment. 2023-11-01 15:59:24 +01:00
Anders Schack-Mulligen
8e9aa5b560 C++: Switch to shared modulus analysis. 2023-11-01 15:59:24 +01:00
Anders Schack-Mulligen
a7f3ef1a6c Rangeanalysis: Parameterise shared modulus analysis. 2023-11-01 15:59:24 +01:00
Anders Schack-Mulligen
8e2b17cd86 Rangeanalysis: Copy C++ ModulusAnalysis file verbatim. 2023-11-01 15:59:24 +01:00
Anders Schack-Mulligen
6d859daf3d Merge pull request #14656 from aschackmull/shared/range-utils
Rangeanalysis: Share ssaRead predicate
2023-11-01 15:57:52 +01:00
Mathias Vorreiter Pedersen
b54b5ae0a9 Merge pull request #14648 from MathiasVP/simplify-invalid-ptr-deref
C++: Remove one use of range analysis in `cpp/invalid-pointer-deref`
2023-11-01 14:42:20 +00:00
Geoffrey White
b3fa59d94b Apply suggestions from code review
Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com>
2023-11-01 13:15:06 +00:00
Tom Hvitved
3c86aad16d Merge pull request #14628 from hvitved/ruby/type-tracking-store-post-update
Ruby: Summarized type-tracking stores should target post-update nodes
2023-11-01 13:54:21 +01:00
yoff
4ce1b680c2 Merge pull request #14654 from yoff/python/update-partial-flow-debug-query
Python: Update debug query to changed API
2023-11-01 13:32:09 +01:00
Anders Schack-Mulligen
048a7c4e42 Rangeanalysis: Rename SsaBound.getAVariable to getVariable. 2023-11-01 11:58:06 +01:00
Anders Schack-Mulligen
48291dd32d Rangeanalysis: Remove superfluous ignoreZeroLowerBound. 2023-11-01 11:51:46 +01:00
Rasmus Lerchedahl Petersen
0b45b63bd2 Python: Update debug query to changed API
The change is commented out by default
which is why no compilation tests failed
when the API changed.
2023-11-01 11:39:51 +01:00
Tom Hvitved
0c5b528d54 Address review comments 2023-11-01 11:32:57 +01:00
Rasmus Lerchedahl Petersen
1366247f4c Python: Add AWS Lambda as a supported framework 2023-11-01 10:51:35 +01:00
Rasmus Lerchedahl Petersen
f7a8a8ae19 Python: Fix QL alert 2023-11-01 09:24:59 +01:00
Mathias Vorreiter Pedersen
9736936e54 Merge pull request #14635 from MathiasVP/assign-pointer-add-and-sub-is-not-bitwise 2023-11-01 00:40:39 +01:00
Erik Krogh Kristensen
ddb145f15f Merge pull request #14645 from erik-krogh/rerun-tests
JS: re-order expected test output of all JS tests
2023-10-31 21:52:52 +01:00
Rasmus Lerchedahl Petersen
38b811b050 Python: Separate -> PhaseDependentFlow 2023-10-31 21:50:33 +01:00
Edward Minnix III
1ec1dd368d Merge pull request #13978 from egregius313/egregius313/java/mad/convert-sensitive-api-to-mad
Java: Convert `SensitiveApi.qll` to use Models-as-Data
2023-10-31 15:25:42 -04:00
Kevin Stubbings
3697ef72c4 Small changes 2023-10-31 12:23:18 -07:00
Mathias Vorreiter Pedersen
6e385cabd8 C++: Add change note. 2023-10-31 19:16:36 +00:00
Mathias Vorreiter Pedersen
37a536baf9 Merge pull request #14650 from jketema/invalid-experimental
C++: Drop `experimental` tag from `cpp/invalid-pointer-deref`
2023-10-31 20:14:25 +01:00
Kevin Stubbings
5cab25662c Address issues 2023-10-31 11:50:51 -07:00
Jeroen Ketema
3478890090 C++: Drop experimental tag from cpp/invalid-pointer-deref 2023-10-31 19:46:22 +01:00
Kevin Stubbings
8ed10317bd Test comment changes 2023-10-31 11:07:41 -07:00
Kevin Stubbings
dd9a2db137 Minor name changes 2023-10-31 11:03:54 -07:00
Kevin Stubbings
020b4becfd Finish up 2023-10-31 11:00:00 -07:00
Mathias Vorreiter Pedersen
b79a5fee14 Merge pull request #14637 from MathiasVP/dataflow-for-realloc
C++: Add a taint model for `realloc`
2023-10-31 18:24:04 +01:00
Geoffrey White
554007b305 Swift: Add a couple more test cases close to the failures. 2023-10-31 17:19:28 +00:00
Geoffrey White
c82eb4dff3 Swift: Test spacing. 2023-10-31 17:18:08 +00:00
Benjamin Rodes
b9ac038de2 Moving change log. 2023-10-31 09:21:01 -07:00
Ian Lynagh
ceb3d14fe0 Merge pull request #14614 from igfoo/igfoo/enum
Kotlin: Make the enum test more precise
2023-10-31 16:18:12 +00:00
Benjamin Rodes
07ded4278f Change log 2023-10-31 09:14:47 -07:00
Paolo Tranquilli
051a77fd79 Merge pull request #14537 from github/alexdenisov/remove-outdated-cli-arg
Swift: remove outdated CLI argument
2023-10-31 17:06:52 +01:00
Benjamin Rodes
18c8d90a1a Adding a model implementation for ODBC.
(cherry picked from commit 04147f8d91cdf018ec03cbfdb953253e23687944)
2023-10-31 08:52:05 -07:00
erik-krogh
688afddaf2 Re-order expected test output of all JS tests 2023-10-31 16:38:22 +01:00
Erik Krogh Kristensen
8f58685b38 Merge pull request #14643 from aibaars/express-req-path
Javascript: add `req.path` as remote flow source
2023-10-31 16:36:48 +01:00
Paolo Tranquilli
567aa1102a Swift: fix toolchain SHAs 2023-10-31 16:20:58 +01:00
Paolo Tranquilli
bc34374075 Swift: switch to downloading the 20.04 toolchain 2023-10-31 16:20:58 +01:00
Paolo Tranquilli
e25a655509 Swift: fix Linux compatibility problem and fetch resource dir from toolchain
This fetches the resource directory directly from the released
toolchains, allowing us to stop prebuilding and assembling them.
Moreover insertion of our resource directory is moved to the lua
tracing configuration (solving a `TODO`) and enhanced. Now all options
that start with the original resource directory (either explicit or
implied) are redirected to our resource directory.

This solves a problem where `-I <original resource dir>/some/path` was
passed to the extractor and did not work.

This works around the 5.9 linux compatibility problem by including the
`PackageDescription` swift modules in the in-dist toolchain. Copying the
toolchain and fixing the `-I` flag was not enough as for some reason
compilation of `PackageDescription.swiftinterface`  was causing a crash
in the SIL pass. We work around that by pre-compiling those modules
during the build and  including `.swiftmodule` files in the resource
directory.

TODO (apart from testing):
* the libraries included in the macOS toolchain are now fat (they were
  intel only before), occupying more space. We should see if we need to
  trim them down.
* there might be other swiftinterface files causing problems on linux
  lurking around...
* if we go with this, we can simplify and trim down the prebuilding we
  do leaving out the resource directory.
2023-10-31 16:20:58 +01:00
Mathias Vorreiter Pedersen
b9dfeb3aac Merge pull request #14444 from alexet/range-cases
CPP: Add some range analysis cases
2023-10-31 15:55:41 +01:00
Anders Schack-Mulligen
34b9791e46 Rangeanalysis: Remove superfluous ignoreSsaReadCopy. 2023-10-31 15:32:25 +01:00
Anders Schack-Mulligen
322e6c91be Rangeanalysis: Remove superfluous specificSsaRead. 2023-10-31 15:30:36 +01:00
Anders Schack-Mulligen
8b6c940e76 Rangeanalysis: Remove superfluous ignoreSsaReadAssignment. 2023-10-31 15:28:37 +01:00
Anders Schack-Mulligen
6d6f89e71e Rangeanalysis: Remove superfluous ignoreSsaReadArithmeticExpr. 2023-10-31 15:25:28 +01:00
Anders Schack-Mulligen
a39a94ca8e Rangeanalysis: Switch to shared ssaRead predicate. 2023-10-31 15:23:05 +01:00
Anders Schack-Mulligen
19644a8f07 Rangeanalysis: Implement shared ssaRead predicate 2023-10-31 15:07:11 +01:00
Rasmus Lerchedahl Petersen
7f6ae8b2ab Python: improve readability 2023-10-31 14:52:37 +01:00
Alexander Eyers-Taylor
11152deeb5 Update cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2023-10-31 13:52:33 +00:00
yoff
f76cde36bb Apply suggestions from code review
Co-authored-by: Taus <tausbn@github.com>
2023-10-31 14:12:24 +01:00
Ian Lynagh
e1f7f3cbd4 Kotlin: Add more info to enum test 2023-10-31 12:17:44 +00:00
Mathias Vorreiter Pedersen
e75562e508 Merge pull request #14633 from github/redsun82/capture-list-vars
Swift: add `VarDecl` children to `CaptureListExpr`
2023-10-31 12:48:14 +01:00
Arthur Baars
5cc94e1105 Express.js: add req.path as remote input source 2023-10-31 12:44:26 +01:00
Arthur Baars
21b7a51d0a Add test case for req.path 2023-10-31 12:44:25 +01:00
Arthur Baars
1479509d93 Re-order expected test ouput 2023-10-31 12:44:25 +01:00
Mathias Vorreiter Pedersen
377da9fa66 C++: Accept test changes. 2023-10-31 11:18:35 +00:00
Mathias Vorreiter Pedersen
4a1bf95a87 C++: Expose a public memset model and use it in the exposure queries. 2023-10-31 11:17:51 +00:00
Mathias Vorreiter Pedersen
e8c18a3883 C++: Add FP in query test. 2023-10-31 11:17:51 +00:00
Chris Smowton
98032d58b8 Merge pull request #14640 from github/smowton/admin/make-go-tests-serial
Go: mark all integration tests non-parallelisable
2023-10-31 10:58:41 +00:00
Stephan Brandauer
5385cc3aaa Merge branch 'main' into kaeluka/publish-automodel-querypack-007 2023-10-31 11:48:22 +01:00
Mathias Vorreiter Pedersen
5b17066e6c Merge pull request #14638 from geoffw0/jsevaltest
Swift: Clean up the swift/unsafe-js-eval test
2023-10-31 11:43:41 +01:00
Paolo Tranquilli
ea04b500a3 Swift: tweak dataflow test 2023-10-31 11:39:25 +01:00
Ian Lynagh
b841d5f923 Merge pull request #14622 from igfoo/igfoo/JavaBinarySourceElement
Kotlin: Add support for JavaBinarySourceElement sources
2023-10-31 10:33:48 +00:00
Tamás Vajk
81b3ff2bb8 Merge pull request #14545 from tamasvajk/standalone/remove-netstandard.library.ref
C#: Handle `netstandard` references in standalone extraction
2023-10-31 11:32:42 +01:00
Chris Smowton
79e1aa0498 Merge pull request #14634 from github/post-release-prep/codeql-cli-2.15.2
Post-release preparation for codeql-cli-2.15.2
2023-10-31 10:24:53 +00:00
Chris Smowton
05a4c7fdc1 Add non-comment lines specifying serialisation group 2023-10-31 10:21:55 +00:00
Mathias Vorreiter Pedersen
66f4eccc30 Merge pull request #14632 from MathiasVP/share-ipa-numbering-for-indirect-nodes
C++: Share IPA numbering for indirect nodes
2023-10-31 11:20:41 +01:00
Stephan Brandauer
9087259b1b Java: add instructions to automodel query publish script 2023-10-31 11:11:22 +01:00
Stephan Brandauer
968127eaa3 Java: release automodel extraction queries 0.0.7 2023-10-31 11:09:02 +01:00
Paolo Tranquilli
5407b57261 Swift: add change note 2023-10-31 10:57:02 +01:00
Paolo Tranquilli
aac6cf60ee Swift: add explicative comment 2023-10-31 10:46:12 +01:00
Paolo Tranquilli
ffff10a7e8 Swift: synthesize CaptureListExpr::getVariable in QL instead of extracting it 2023-10-31 10:44:50 +01:00
Paolo Tranquilli
7bae2d9192 Swift: fix tests 2023-10-31 10:44:41 +01:00
Geoffrey White
6b031a4623 Swift: Fix the example links properly. 2023-10-31 08:52:24 +00:00
Geoffrey White
785175e77f Swift: Fix QL-for-QL warning. 2023-10-31 08:49:48 +00:00
Geoffrey White
bfd852aacd Swift: Fix the example links. 2023-10-31 08:48:56 +00:00
Chris Smowton
ec72150893 Go: mark all integration tests non-parallelisable 2023-10-30 22:16:26 +00:00
Tom Hvitved
435b7df764 Merge pull request #14607 from hvitved/csharp/type-ref-dedup
C#: Only use `getTypeRef` when there is not already a type available
2023-10-30 19:52:58 +01:00
Geoffrey White
8913638b25 Swift: I'm happy with 'high' precision for this query (as the Go version already is). 2023-10-30 18:45:19 +00:00
Geoffrey White
b259a0ff6a Swift: get rid of getRemoteData() in the tests, it's obfuscating results. 2023-10-30 17:48:51 +00:00
Geoffrey White
c8706e2ad7 Swift: Add some annotations to the clarify UnsafeJSEval.swift test. 2023-10-30 17:43:37 +00:00
Mathias Vorreiter Pedersen
65081a9a1f C++: Add change note. 2023-10-30 17:11:44 +00:00
Mathias Vorreiter Pedersen
08b528b5c4 C++: Add a taint-model for 'realloc' and accept test changes. 2023-10-30 17:08:01 +00:00
Mathias Vorreiter Pedersen
0837e400a2 C++: Add failing test. 2023-10-30 17:05:43 +00:00
Mathias Vorreiter Pedersen
efe064284b C++: Add up and downgrade scripts. 2023-10-30 16:07:57 +00:00
Mathias Vorreiter Pedersen
86fe5b47db C++: Remove 'assignpaddexpr' and 'assignpsubexpr' from the 'assign_bitwise_expr' type. 2023-10-30 16:06:53 +00:00
github-actions[bot]
2b939fdf08 Post-release preparation for codeql-cli-2.15.2 2023-10-30 16:06:51 +00:00
Paolo Tranquilli
f81a3ec464 Swift: add VarDecl children to CaptureListExpr 2023-10-30 17:04:53 +01:00
Mathias Vorreiter Pedersen
375f0ea8b6 C++: Update documentation. 2023-10-30 15:57:30 +00:00
Mathias Vorreiter Pedersen
1e699ec0e5 C++: Simplify 'InvalidPointerToDereference.qll' now that the difference between 'derefSource' and 'pai' is always 0. 2023-10-30 15:53:48 +00:00
Mathias Vorreiter Pedersen
c8edf3151b C++: Remove the use of range analysis in 'invalidPointerToDerefSource'. 2023-10-30 15:47:47 +00:00
Tony Torralba
45cf50c2af Apply JMS sink only when there isn't an implementation available 2023-10-30 15:56:24 +01:00
Geoffrey White
c233094846 Swift: Change note. 2023-10-30 14:33:43 +00:00
Geoffrey White
fa3d401226 Swift: Update the qhelp. 2023-10-30 14:33:43 +00:00
Geoffrey White
7cf5210063 Swift: Port the qhelp examples to Swift. 2023-10-30 14:33:43 +00:00
Geoffrey White
9a95b9bcda Swift: Enable the isLineAnchoredHostnameRegExp case (not working). 2023-10-30 14:33:42 +00:00
Geoffrey White
c09df2e3f1 Swift: Add test cases for the isLineAnchoredHostnameRegExp query case. 2023-10-30 14:33:42 +00:00
Geoffrey White
8f115bfd06 Swift: Implement 'isUsedAsReplace'. 2023-10-30 14:33:42 +00:00
Mathias Vorreiter Pedersen
91d224eea5 Merge pull request #14623 from alexet/dataflow-fps
CPP: Add dataflow FP with output arguments
2023-10-30 14:30:51 +00:00
Alex Eyers-Taylor
fb0f9ec601 CPP: Add missing rnage analysis ranges in test. 2023-10-30 14:17:03 +00:00
Alexander Eyers-Taylor
b8d45ae927 Update cpp/ql/test/library-tests/dataflow/dataflow-tests/flowOut.cpp
Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
2023-10-30 14:04:45 +00:00
Ian Lynagh
e2ef0dc71d Merge pull request #14621 from igfoo/igfoo/getFileClassFqName_IrField
Kotlin: Fix getFileClassFqName for IrField
2023-10-30 13:54:08 +00:00
Ian Lynagh
d46442245b Merge pull request #14518 from igfoo/igfoo/trap_files
Kotlin: Log when we start and finish writing to TRAP files
2023-10-30 13:53:04 +00:00
Geoffrey White
435638a5bb Swift: Port the JS tests to Swift. 2023-10-30 13:08:11 +00:00
Geoffrey White
954b0612d5 Swift: Initial state of the existing test. 2023-10-30 13:08:10 +00:00
Geoffrey White
14db0dfcc7 Swift: Fairly minimal fix to get the query and test working for Swift. 2023-10-30 13:08:10 +00:00
Geoffrey White
c040d4847b Swift: Copy MissingRegexAnchor query from JS. 2023-10-30 13:08:10 +00:00
Harry Maclean
dc9f171ee6 Merge pull request #14631 from hmac/hmac-dynamic-neutral-model
JS/Ruby/Python: Add neutralModel extensible predicate
2023-10-30 12:50:09 +00:00
Mathias Vorreiter Pedersen
b4958e7d58 C++: Accept path changes. 2023-10-30 12:44:30 +00:00
Mathias Vorreiter Pedersen
a077b70d66 C++: Accept test changes. 2023-10-30 11:54:24 +00:00
Mathias Vorreiter Pedersen
535d1e2565 C++: Define indirect instructions (and operands) using a 'Node0Impl' column instead of an instruction (or operand). 2023-10-30 11:54:24 +00:00
Ian Lynagh
55df481e5c Kotlin: Add support for JavaBinarySourceElement sources 2023-10-30 11:43:36 +00:00
Harry Maclean
083be305e1 Shared: Add neutralModel extensible predicate
The neutralModel extensible predicate already exists in Java and C#, so
this change brings the dynamic languages more in line with static
languages. The Model Editor uses this predicate to mark endpoints as
"not interesting" from a data flow perspective.
2023-10-30 11:31:57 +00:00
Harry Maclean
38ecde0cc1 Shared: Include data extensions in workspace
This change allows codeql to see data extensions stored in the .github
directory inside the codeql repo. This is useful when using the CodeQL
Model Editor whilst working inside the codeql repo.
2023-10-30 11:31:56 +00:00
Mathias Vorreiter Pedersen
3a9ffe189e Merge pull request #14567 from github/redsun82/swift-case-variables
Swift: clean up `VarDecl`, `NamedPattern` and `SwitchStmt` interactions
2023-10-30 11:23:38 +00:00
Mathias Vorreiter Pedersen
9e2f0b5ed0 Merge branch 'main' into redsun82/swift-case-variables 2023-10-30 10:14:45 +00:00
Tom Hvitved
bf3fb685ad Python: Sync in changes to SummaryTypeTracker.qll 2023-10-30 10:52:07 +01:00
Tom Hvitved
14cfb82a8c Ruby: Summarized type-tracking stores should target post-update nodes 2023-10-30 10:47:29 +01:00
Kevin Stubbings
e0782683eb Added gin cors framework 2023-10-27 17:50:43 -07:00
Alex Eyers-Taylor
60f3598da9 CPP: Add dataflow FP with output arguments 2023-10-27 19:07:10 +01:00
Ian Lynagh
e25c0498d4 Kotlin: Fix getFileClassFqName for IrField 2023-10-27 18:00:33 +01:00
Mathias Vorreiter Pedersen
28eb2caacb Swift: Accept test changes. 2023-10-27 16:30:01 +01:00
Mathias Vorreiter Pedersen
6538a7645d Swift: Add up and downgrade scripts. 2023-10-27 15:55:12 +01:00
Rasmus Lerchedahl Petersen
1f8a51cffe Python: add module for post-update flow
The logic for adding flow out of post-update-nodes
was also duplicated, so I added a module for that also.

The two modules are now only used together. I did not
fuse them, though, as I think they may not be used
together in the case of use-use-flow.
2023-10-27 15:07:49 +02:00
Rasmus Lerchedahl Petersen
e745df6478 Python: module for import time flow
The logic for separating local flow into _import time_
and _runtime_ was duplicated a few times.
Create a module for it instead, and add a good qldoc.
2023-10-27 15:07:49 +02:00
Tom Hvitved
6ad8a4db1c C#: Only use getTypeRef when there is not already a type available 2023-10-27 14:11:55 +02:00
Ian Lynagh
0cf702a74f Kotlin: Tweak the logs test to not be confused by the new logs 2023-10-27 12:04:43 +01:00
Ian Lynagh
3c5b9ce0cd Kotlin: Make the enum test more precise
In Kotlin 2 mode, there are more library classes matching Enum%, so the
output was spuriously different.
2023-10-27 11:15:12 +01:00
Max Schaefer
104700f6d3 Address review comment. 2023-10-27 10:19:28 +01:00
Tony Torralba
7af3d239ab Java: Add JMS sink to java/unsafe-deserialization 2023-10-26 16:46:19 +02:00
Max Schaefer
08cc8b8e80 Autoformat. 2023-10-26 15:36:06 +01:00
Max Schaefer
f42bd28ca9 Port changes to Ruby. 2023-10-26 15:06:45 +01:00
Max Schaefer
741735cc83 Port changes to JavaScript. 2023-10-26 14:47:24 +01:00
Max Schaefer
3939167ba2 Include more details in the message for py/weak-cryptographic-algorithm.
Specifically, we add a link to the location where the cryptographic algorithm is configured, which can be far away from its use.
2023-10-26 11:28:09 +01:00
Kevin Stubbings
dafcd5ec98 Added support for Gin CORS 2023-10-25 17:23:10 -07:00
Maiky
a1e38c3444 Remove unnecessary imports and add returns 2023-10-26 01:16:43 +02:00
Ed Minnix
9d90c24006 Refactor to using MethodCall instead of MethodAccess 2023-10-25 14:31:56 -04:00
Ed Minnix
f288ddc3d5 Add signature back to trilead ssh2 model 2023-10-25 14:31:56 -04:00
Ed Minnix
d923784ae4 Add signatures to models 2023-10-25 14:31:56 -04:00
Ed Minnix
90c63ab6b0 Remove additional net.schmizz.sshj models 2023-10-25 14:31:56 -04:00
Edward Minnix III
2fb4dfeb90 TrustType should be nested in sun.security.pkcs11.Secmod models
Co-authored-by: Jami <57204504+jcogs33@users.noreply.github.com>
2023-10-25 14:31:55 -04:00
Ed Minnix
665b140a8a Make SaltAndParams be nested 2023-10-25 14:31:55 -04:00
Edward Minnix III
700201556c Remove extra model
Co-authored-by: Jami <57204504+jcogs33@users.noreply.github.com>
2023-10-25 14:31:55 -04:00
Ed Minnix
58dae6d1c6 Set provenance of models from otherApiCallableCredentialParam to manual and remove extra models 2023-10-25 14:31:55 -04:00
Edward Minnix III
2a91743477 Re-add IvParameterSpec constructor to otherApiCallableCredentialParam
Co-authored-by: Tony Torralba <atorralba@users.noreply.github.com>
2023-10-25 14:31:55 -04:00
Ed Minnix
a28f19c857 Remove initialization vectors from SensitiveApi 2023-10-25 14:31:55 -04:00
Ed Minnix
c689065f83 Experiment: Remove IVs from credentials 2023-10-25 14:31:55 -04:00
Ed Minnix
855d96db66 Remove extra models 2023-10-25 14:31:55 -04:00
Ed Minnix
d85284da55 Update change note file date 2023-10-25 14:31:55 -04:00
Ed Minnix
02c98fae5f Use hq-generated provenance 2023-10-25 14:31:55 -04:00
Ed Minnix
1ad06f3293 Add missing GaloisCounterMode model 2023-10-25 14:31:55 -04:00
Ed Minnix
9c15cf18e8 Refactor deprecated predicates to use new classes
Modified the predicates in `SensitiveApi` to rely on the new classes
which are using models as data. This allows us to remove the old
predicates containing the pre-MaD versions of the models.
2023-10-25 14:31:55 -04:00
Ed Minnix
3b0b5e403c Replace crypto-parameter with credentials-key 2023-10-25 14:31:55 -04:00
Ed Minnix
a2bcc97a74 Remove CipherBlockChaining#init 2023-10-25 14:31:55 -04:00
Ed Minnix
743814a234 Delete private methods 2023-10-25 14:31:55 -04:00
Ed Minnix
c2d072e3f8 Remove redundant Cipher init methods
Remove redundant `init` methods which are overriding `FeedbackCipher`
and `SymmetricCipher`.
2023-10-25 14:31:54 -04:00
Ed Minnix
22d968fba3 Delete private methods 2023-10-25 14:31:54 -04:00
Ed Minnix
31b069041f Initialization vector models 2023-10-25 14:31:54 -04:00
Ed Minnix
a8eb95a688 Remove redundant engineUnwrap method models
Most implementations of `engineUnwrap` are overriding the method from
`javax.crypto.CipherSpi`. Therefore, these models can be compressed into
a single model.
2023-10-25 14:31:54 -04:00
Ed Minnix
64d23d4f9b Delete private methods 2023-10-25 14:31:54 -04:00
Ed Minnix
5b2d226c35 Remove unneeded models 2023-10-25 14:31:54 -04:00
Ed Minnix
1edca19419 Remove redundant KeyStoreSpi models
`java.security.KeyStoreSpi` is an abstract class. This removes its
subclasses' models, and instead uses model-as-data's capability to use
subclasses.
2023-10-25 14:31:54 -04:00
Ed Minnix
24c809b3b5 Move credentials-% sink kinds to "shared" status 2023-10-25 14:31:54 -04:00
Edward Minnix III
72a1289eba Rename class to CredentialsSinkNode to better align with naming convention
Co-authored-by: Jami <57204504+jcogs33@users.noreply.github.com>
2023-10-25 14:31:54 -04:00
Ed Minnix
c6641dfbf3 fix model validator to credentials-password 2023-10-25 14:31:54 -04:00
Ed Minnix
a85df81b67 Rename sink kind to "credentials-username" to match naming convention 2023-10-25 14:31:54 -04:00
Ed Minnix
0612b3795a Rename sink kind to "credentials-password" to match naming convention 2023-10-25 14:31:54 -04:00
Ed Minnix
3ee0fa9bc4 Add deprecation messages 2023-10-25 14:31:54 -04:00
Ed Minnix
b77b3763be Fix com.amazonaws.auth models 2023-10-25 14:31:54 -04:00
Ed Minnix
8eeb861963 ch.ethz.ssh2 fixes 2023-10-25 14:31:54 -04:00
Edward Minnix III
2f53adf2c2 Fix typo
Co-authored-by: Jami <57204504+jcogs33@users.noreply.github.com>
2023-10-25 14:31:54 -04:00
Ed Minnix
dbb5aa9aad Change note 2023-10-25 14:31:54 -04:00
Ed Minnix
083a5068c3 Remove unnecessary models 2023-10-25 14:31:53 -04:00
Ed Minnix
886c85ddc1 Fix net.schmizz.sshj models 2023-10-25 14:31:53 -04:00
Ed Minnix
958c6ff289 Remove credential-other 2023-10-25 14:31:53 -04:00
Ed Minnix
ee6cb96d07 Add a superclass for credential nodes 2023-10-25 14:31:53 -04:00
Ed Minnix
3219edc603 Change credential-other to more appropriate sink kinds 2023-10-25 14:31:53 -04:00
Ed Minnix
6b94b77a0a Remove spaces in sig field of models 2023-10-25 14:31:53 -04:00
Ed Minnix
f8c3b2977a Fix credential-other 2023-10-25 14:31:53 -04:00
Ed Minnix
f783ca7940 Fix credential-username 2023-10-25 14:31:53 -04:00
Ed Minnix
96d6ecb108 Fix crypto parameters 2023-10-25 14:31:53 -04:00
Ed Minnix
35e19eac96 Fix password models 2023-10-25 14:31:53 -04:00
Ed Minnix
4f8908106b Refactor HardcodedCredentials to use new SensitiveApi api 2023-10-25 14:31:53 -04:00
Ed Minnix
f7c07d55ed Credential-other sinks 2023-10-25 14:31:53 -04:00
Ed Minnix
49218cdbfb Credential-username models 2023-10-25 14:31:53 -04:00
Ed Minnix
18661eee77 Crypto-parameter models 2023-10-25 14:31:53 -04:00
Ed Minnix
66486b08dc Password models 2023-10-25 14:31:53 -04:00
Ed Minnix
4aec302fb7 Create new sink kinds 2023-10-25 14:31:53 -04:00
Maiky
eccde3f4f1 Add Tests 2023-10-25 18:31:51 +02:00
Rasmus Wriedt Larsen
be494b73d4 Python: Minor cleanup for string pool interaction
This doesn't really seem to impact performance, is just a bit cleaner way to write the QL code.

In the worst case, since we do string concat with empty string, we would need to load string + attempt to store new string in string pool, which is useless since we can surely just reuse the integer ID.

-- Previously

Evaluated non-recursive predicate ImportResolution#f829f0f0::ImportResolution::getImmediateModuleReference#1#ff#reorder_1_0#join_rhs#CSE@5fdc6eia in 1ms (size: 2).
Evaluated relational algebra for predicate ImportResolution#f829f0f0::ImportResolution::getImmediateModuleReference#1#ff#reorder_1_0#join_rhs#CSE@5fdc6eia with tuple counts:
         1   ~0%    {1} r1 = CONSTANT(unique string)[""]

         1   ~0%    {1} r2 = CONSTANT(unique string)[".__init__"]

         2   ~0%    {1} r3 = r1 UNION r2
                    return r3

Evaluated recursive predicate ImportResolution#f829f0f0::ImportResolution::getImmediateModuleReference#1#ff#reorder_1_0@b4f54xlv in 72ms on iteration 1 (delta size: 26339).
Evaluated relational algebra for predicate ImportResolution#f829f0f0::ImportResolution::getImmediateModuleReference#1#ff#reorder_1_0@b4f54xlv on iteration 1 running pipeline base with tuple counts:
         6382   ~0%    {3} r1 = JOIN ImportResolution#f829f0f0::ImportResolution::getImmediateModuleReference#1#ff#reorder_1_0#join_rhs#CSE WITH Module#68efc075::Module::getFile#0#dispred#ff CARTESIAN PRODUCT OUTPUT Rhs.1, Lhs.0, Rhs.0
         6066   ~2%    {4} r2 = JOIN r1 WITH Module#68efc075::isPreferredModuleForName#2#ff ON FIRST 1 OUTPUT Lhs.2, _, Lhs.1, Rhs.1
                       {2} r3 = REWRITE r2 WITH Tmp.1 := "", Out.1 := InverseAppend(Tmp.1,In.2,In.3) KEEPING 2
         3721   ~0%    {2} r4 = SCAN r3 OUTPUT In.1, In.0
        25945   ~2%    {2} r5 = JOIN r4 WITH ImportResolution#f829f0f0::ImportResolution::getReferenceToModuleName#1#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1

           38   ~4%    {3} r6 = SCAN SsaDefinitions#9197156e::SsaSource::init_module_submodule_defn#2#ff OUTPUT In.1, _, In.0
           38   ~1%    {3} r7 = REWRITE r6 WITH Out.1 := -1
           38   ~1%    {2} r8 = JOIN r7 WITH py_scope_flow_021#join_rhs ON FIRST 2 OUTPUT Rhs.2, Lhs.2
           38   ~0%    {2} r9 = JOIN r8 WITH Module#68efc075::Module::getPackageName#0#dispred#ff ON FIRST 1 OUTPUT Lhs.1, Rhs.1
          394   ~2%    {2} r10 = JOIN r9 WITH Essa#24e22a14::EssaVariable::getSourceVariable#0#dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1
          394   ~0%    {3} r11 = JOIN r10 WITH DataFlowPublic#c4b6ce7e::EssaNode#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Rhs.1

          394   ~0%    {5} r12 = JOIN r11 WITH Essa#24e22a14::EssaVariable::getName#0#dispred#ff ON FIRST 1 OUTPUT _, Lhs.2, Lhs.1, Rhs.1, _
          394   ~0%    {2} r13 = REWRITE r12 WITH Tmp.0 := ".", Tmp.4 := "", Out.0 := (In.2 ++ Tmp.0 ++ In.3 ++ Tmp.4) KEEPING 2

          394   ~0%    {5} r14 = JOIN r11 WITH Essa#24e22a14::EssaVariable::getName#0#dispred#ff ON FIRST 1 OUTPUT _, Lhs.2, Lhs.1, Rhs.1, _
          394   ~1%    {2} r15 = REWRITE r14 WITH Tmp.0 := ".", Tmp.4 := ".__init__", Out.0 := (In.2 ++ Tmp.0 ++ In.3 ++ Tmp.4) KEEPING 2

          788   ~3%    {2} r16 = r13 UNION r15
          401   ~2%    {2} r17 = JOIN r16 WITH Module#68efc075::isPreferredModuleForName#2#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1
          394   ~1%    {2} r18 = JOIN r17 WITH Module#68efc075::Module::getFile#0#dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.1, Rhs.1

        26339   ~1%    {2} r19 = r5 UNION r18
                       return r19

-- Now

Evaluated recursive predicate ImportResolution#f829f0f0::ImportResolution::getImmediateModuleReference#1#ff#reorder_1_0@409a0xhe in 8ms on iteration 1 (delta size: 26339).
Evaluated relational algebra for predicate ImportResolution#f829f0f0::ImportResolution::getImmediateModuleReference#1#ff#reorder_1_0@409a0xhe on iteration 1 running pipeline base with tuple counts:
         3033   ~0%    {2} r1 = JOIN Module#68efc075::Module::getFile#0#dispred#ff_10#join_rhs WITH Module#68efc075::isPreferredModuleForName#2#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1

         3033   ~0%    {4} r2 = JOIN Module#68efc075::Module::getFile#0#dispred#ff_10#join_rhs WITH Module#68efc075::isPreferredModuleForName#2#ff ON FIRST 1 OUTPUT Lhs.1, _, Rhs.1, _
                       {2} r3 = REWRITE r2 WITH Tmp.1 := "", Tmp.3 := ".__init__", Out.1 := InverseAppend(Tmp.1,Tmp.3,In.2) KEEPING 2
          688   ~0%    {2} r4 = SCAN r3 OUTPUT In.1, In.0

         3721   ~0%    {2} r5 = r1 UNION r4
        25945   ~2%    {2} r6 = JOIN r5 WITH ImportResolution#f829f0f0::ImportResolution::getReferenceToModuleName#1#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1

           38   ~4%    {3} r7 = SCAN SsaDefinitions#9197156e::SsaSource::init_module_submodule_defn#2#ff OUTPUT In.1, _, In.0
           38   ~1%    {3} r8 = REWRITE r7 WITH Out.1 := -1
           38   ~1%    {2} r9 = JOIN r8 WITH py_scope_flow_021#join_rhs ON FIRST 2 OUTPUT Rhs.2, Lhs.2
           38   ~0%    {2} r10 = JOIN r9 WITH Module#68efc075::Module::getPackageName#0#dispred#ff ON FIRST 1 OUTPUT Lhs.1, Rhs.1
          394   ~2%    {2} r11 = JOIN r10 WITH Essa#24e22a14::EssaVariable::getSourceVariable#0#dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1
          394   ~0%    {3} r12 = JOIN r11 WITH DataFlowPublic#c4b6ce7e::EssaNode#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Rhs.1

          394   ~2%    {4} r13 = JOIN r12 WITH Essa#24e22a14::EssaVariable::getName#0#dispred#ff ON FIRST 1 OUTPUT _, Lhs.2, Lhs.1, Rhs.1
          394   ~0%    {2} r14 = REWRITE r13 WITH Tmp.0 := ".", Out.0 := (In.2 ++ Tmp.0 ++ In.3) KEEPING 2

          394   ~0%    {5} r15 = JOIN r12 WITH Essa#24e22a14::EssaVariable::getName#0#dispred#ff ON FIRST 1 OUTPUT _, Lhs.2, Lhs.1, Rhs.1, _
          394   ~5%    {2} r16 = REWRITE r15 WITH Tmp.0 := ".", Tmp.0 := (In.2 ++ Tmp.0 ++ In.3), Tmp.4 := ".__init__", Out.0 := (Tmp.0 ++ Tmp.4) KEEPING 2

          788   ~0%    {2} r17 = r14 UNION r16
          401   ~1%    {2} r18 = JOIN r17 WITH Module#68efc075::isPreferredModuleForName#2#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1
          394   ~1%    {2} r19 = JOIN r18 WITH Module#68efc075::Module::getFile#0#dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.1, Rhs.1

        26339   ~0%    {2} r20 = r6 UNION r19
                       return r20
2023-10-25 14:53:51 +01:00
Paolo Tranquilli
fb470e4140 Swift: remove useless commented-out line 2023-10-25 12:15:25 +02:00
Geoffrey White
bf503849ea Swift: Fixup line numbers after merge. 2023-10-25 11:09:13 +01:00
Geoffrey White
bf6e6a1e68 Merge branch 'main' into stringwith 2023-10-25 10:58:25 +01:00
Paolo Tranquilli
a245d0019e Swift: tiny cosmetic tweak 2023-10-25 10:56:21 +02:00
Paolo Tranquilli
9196939384 Swift: canonicalize all VarDecls 2023-10-25 10:38:17 +02:00
Geoffrey White
d2d70cc782 Swift: Change note. 2023-10-24 16:17:21 +01:00
Geoffrey White
79f675cdb7 Swift: Fix a model. 2023-10-24 16:17:21 +01:00
Geoffrey White
a5206028b0 Swift: Expand a test to explore why it fails (lack of pointer models and closure capture flow). 2023-10-24 16:17:21 +01:00
Geoffrey White
d3063e849e Swift: Model string closure methods. 2023-10-24 12:58:38 +01:00
Geoffrey White
4cf40ed259 Swift: Add a test case for withMutableCharacters. 2023-10-23 23:30:19 +01:00
Paolo Tranquilli
2f0ee12584 Swift: fix patterns/bound_and_unbound.ql test 2023-10-23 17:36:42 +02:00
Paolo Tranquilli
f22d60f011 Swift: clean up VarDecl, NamedPattern and SwitchStmt interactions
* `variables` under `CaseStmt` are now AST children, which solves
  orphan `VarDecl`s in that case
* reordered `CaseStmt` AST children to be `labels > variables > body`
  (was `body > labels`)
* made `NamedPattern::getVarDecl` an extracted property instead of
  `getName`
* The above led to duplicate DB entities because of a quirk in the
  Swift compiler code. This is solved by tweaking the extraction of
  `variables` under `CaseStmt` to not use `getCaseBodyVariables`.
2023-10-23 17:36:42 +02:00
amammad
a0e2e1ef21 add to Frameworks.qll 2023-10-21 19:49:27 +02:00
amammad
1fe565a46f cherrypy framework file system access Sinks are added 2023-10-21 19:47:30 +02:00
Tamas Vajk
3f1e145d2c C#: Rework .net framework reference removal 2023-10-20 14:40:13 +02:00
Tamas Vajk
36f1070b93 Adjust expected test files 2023-10-20 09:42:00 +02:00
Tamas Vajk
fc1fc05d16 C#: Rework .net framework reference removal 2023-10-20 09:22:14 +02:00
Tamas Vajk
fbfafbfdd4 C#: Remove netstandard.library.ref from the references 2023-10-19 15:49:16 +02:00
Alex Denisov
eb3e140008 Swift: remove outdated CLI argument 2023-10-18 14:44:47 +02:00
Ian Lynagh
0a0ce1f202 Kotlin: Log when we start and finish writing to TRAP files 2023-10-16 16:14:23 +01:00
Maiky
20bf3c7f67 Apply suggestions from code review
Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com>
2023-10-15 15:47:19 +02:00
Alex Eyers-Taylor
3ac3169278 CPP: Add some range analysis cases 2023-10-10 20:01:14 +01:00
Remco Vermeulen
76e56cdac7 Adjust query severities 2023-10-09 12:52:09 -07:00
amammad
ad2631202d fix comments 2023-10-08 21:32:04 +02:00
amammad
6c8cc79b4d v1 2023-10-08 21:24:54 +02:00
Maiky
52007fb9a2 Change v3 to v2 2023-09-17 21:42:18 +02:00
Maiky
08c54767f2 Correct Ldap Unauth Bind Sink 2023-07-05 17:56:49 +02:00
Maiky
d654e98650 Add empty string as source 2023-06-18 22:21:12 +02:00
Maiky
1a9bfb38aa Correct barrier 2023-06-05 01:25:17 +02:00
Maiky
bf9d0b93d7 Add Improper LDAP Auth Query (CWE-287) 2023-06-03 23:20:11 +02:00
Sam Browning
1a51c015b4 Add requirements.txt 2023-04-27 15:19:45 -04:00
2488 changed files with 174075 additions and 81638 deletions

View File

@@ -29,6 +29,7 @@ provide:
- "swift/extractor-pack/codeql-extractor.yml"
- "swift/integration-tests/qlpack.yml"
- "ql/extractor-pack/codeql-extractor.yml"
- ".github/codeql/extensions/**/codeql-pack.yml"
versionPolicies:
default:

View File

@@ -145,9 +145,9 @@ namespace Semmle.Autobuild.Cpp.Tests
bool IBuildActions.IsMacOs() => IsMacOs;
public bool IsArm { get; set; }
public bool IsRunningOnAppleSilicon { get; set; }
bool IBuildActions.IsArm() => IsArm;
bool IBuildActions.IsRunningOnAppleSilicon() => IsRunningOnAppleSilicon;
string IBuildActions.PathCombine(params string[] parts)
{

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Removed @assignpaddexpr and @assignpsubexpr from @assign_bitwise_expr
compatibility: full

View File

@@ -1,3 +1,17 @@
## 0.12.0
### Breaking Changes
* The expressions `AssignPointerAddExpr` and `AssignPointerSubExpr` are no longer subtypes of `AssignBitwiseOperation`.
### Minor Analysis Improvements
* The "Returning stack-allocated memory" (`cpp/return-stack-allocated-memory`) query now also detects returning stack-allocated memory allocated by calls to `alloca`, `strdupa`, and `strndupa`.
* Added models for `strlcpy` and `strlcat`.
* Added models for the `sprintf` variants from the `StrSafe.h` header.
* Added SQL API models for `ODBC`.
* Added taint models for `realloc` and related functions.
## 0.11.0
### Breaking Changes

View File

@@ -0,0 +1,13 @@
## 0.12.0
### Breaking Changes
* The expressions `AssignPointerAddExpr` and `AssignPointerSubExpr` are no longer subtypes of `AssignBitwiseOperation`.
### Minor Analysis Improvements
* The "Returning stack-allocated memory" (`cpp/return-stack-allocated-memory`) query now also detects returning stack-allocated memory allocated by calls to `alloca`, `strdupa`, and `strndupa`.
* Added models for `strlcpy` and `strlcat`.
* Added models for the `sprintf` variants from the `StrSafe.h` header.
* Added SQL API models for `ODBC`.
* Added taint models for `realloc` and related functions.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.11.0
lastReleaseVersion: 0.12.0

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 0.11.0
version: 0.12.0
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -31,6 +31,11 @@ abstract class MustFlowConfiguration extends string {
*/
abstract predicate isSink(Operand sink);
/**
* Holds if data flow through `instr` is prohibited.
*/
predicate isBarrier(Instruction instr) { none() }
/**
* Holds if the additional flow step from `node1` to `node2` must be taken
* into account in the analysis.
@@ -48,18 +53,21 @@ abstract class MustFlowConfiguration extends string {
*/
final predicate hasFlowPath(MustFlowPathNode source, MustFlowPathSink sink) {
this.isSource(source.getInstruction()) and
source.getASuccessor+() = sink
source.getASuccessor*() = sink
}
}
/** Holds if `node` flows from a source. */
pragma[nomagic]
private predicate flowsFromSource(Instruction node, MustFlowConfiguration config) {
config.isSource(node)
or
exists(Instruction mid |
step(mid, node, config) and
flowsFromSource(mid, pragma[only_bind_into](config))
not config.isBarrier(node) and
(
config.isSource(node)
or
exists(Instruction mid |
step(mid, node, config) and
flowsFromSource(mid, pragma[only_bind_into](config))
)
)
}

View File

@@ -81,6 +81,14 @@ class Node0Impl extends TIRDataFlowNode0 {
/** Gets the operands corresponding to this node, if any. */
Operand asOperand() { result = this.(OperandNode0).getOperand() }
/** Gets the location of this node. */
final Location getLocation() { result = this.getLocationImpl() }
/** INTERNAL: Do not use. */
Location getLocationImpl() {
none() // overridden by subclasses
}
/** INTERNAL: Do not use. */
string toStringImpl() {
none() // overridden by subclasses
@@ -131,9 +139,15 @@ abstract class InstructionNode0 extends Node0Impl {
override DataFlowType getType() { result = getInstructionType(instr, _) }
override string toStringImpl() {
// This predicate is overridden in subclasses. This default implementation
// does not use `Instruction.toString` because that's expensive to compute.
result = instr.getOpcode().toString()
if instr.(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
then result = "this"
else result = instr.getAst().toString()
}
override Location getLocationImpl() {
if exists(instr.getAst().getLocation())
then result = instr.getAst().getLocation()
else result instanceof UnknownDefaultLocation
}
final override predicate isGLValue() { exists(getInstructionType(instr, true)) }
@@ -173,7 +187,17 @@ abstract class OperandNode0 extends Node0Impl {
override DataFlowType getType() { result = getOperandType(op, _) }
override string toStringImpl() { result = op.toString() }
override string toStringImpl() {
if op.getDef().(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
then result = "this"
else result = op.getDef().getAst().toString()
}
override Location getLocationImpl() {
if exists(op.getDef().getAst().getLocation())
then result = op.getDef().getAst().getLocation()
else result instanceof UnknownDefaultLocation
}
final override predicate isGLValue() { exists(getOperandType(op, true)) }
}
@@ -632,20 +656,20 @@ predicate jumpStep(Node n1, Node n2) {
v = globalUse.getVariable() and
n1.(FinalGlobalValue).getGlobalUse() = globalUse
|
globalUse.getIndirectionIndex() = 1 and
globalUse.getIndirection() = 1 and
v = n2.asVariable()
or
v = n2.asIndirectVariable(globalUse.getIndirectionIndex())
v = n2.asIndirectVariable(globalUse.getIndirection())
)
or
exists(Ssa::GlobalDef globalDef |
v = globalDef.getVariable() and
n2.(InitialGlobalValue).getGlobalDef() = globalDef
|
globalDef.getIndirectionIndex() = 1 and
globalDef.getIndirection() = 1 and
v = n1.asVariable()
or
v = n1.asIndirectVariable(globalDef.getIndirectionIndex())
v = n1.asIndirectVariable(globalDef.getIndirection())
)
)
}

View File

@@ -44,11 +44,12 @@ private newtype TIRDataFlowNode =
TIndirectArgumentOutNode(ArgumentOperand operand, int indirectionIndex) {
Ssa::isModifiableByCall(operand, indirectionIndex)
} or
TRawIndirectOperand(Operand op, int indirectionIndex) {
Ssa::hasRawIndirectOperand(op, indirectionIndex)
TRawIndirectOperand0(Node0Impl node, int indirectionIndex) {
Ssa::hasRawIndirectOperand(node.asOperand(), indirectionIndex)
} or
TRawIndirectInstruction(Instruction instr, int indirectionIndex) {
Ssa::hasRawIndirectInstruction(instr, indirectionIndex)
TRawIndirectInstruction0(Node0Impl node, int indirectionIndex) {
not exists(node.asOperand()) and
Ssa::hasRawIndirectInstruction(node.asInstruction(), indirectionIndex)
} or
TFinalParameterNode(Parameter p, int indirectionIndex) {
exists(Ssa::FinalParameterUse use |
@@ -431,6 +432,10 @@ private class Node0 extends Node, TNode0 {
override Declaration getFunction() { result = node.getFunction() }
override Location getLocationImpl() { result = node.getLocation() }
override string toStringImpl() { result = node.toString() }
override DataFlowType getType() { result = node.getType() }
override predicate isGLValue() { node.isGLValue() }
@@ -447,18 +452,6 @@ class InstructionNode extends Node0 {
/** Gets the instruction corresponding to this node. */
Instruction getInstruction() { result = instr }
override Location getLocationImpl() {
if exists(instr.getAst().getLocation())
then result = instr.getAst().getLocation()
else result instanceof UnknownDefaultLocation
}
override string toStringImpl() {
if instr.(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
then result = "this"
else result = instr.getAst().toString()
}
}
/**
@@ -472,18 +465,6 @@ class OperandNode extends Node, Node0 {
/** Gets the operand corresponding to this node. */
Operand getOperand() { result = op }
override Location getLocationImpl() {
if exists(op.getDef().getAst().getLocation())
then result = op.getDef().getAst().getLocation()
else result instanceof UnknownDefaultLocation
}
override string toStringImpl() {
if op.getDef().(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
then result = "this"
else result = op.getDef().getAst().toString()
}
}
/**
@@ -918,48 +899,146 @@ Type getTypeImpl(Type t, int indirectionIndex) {
result instanceof UnknownType
}
/**
* INTERNAL: Do not use.
*
* A node that represents the indirect value of an operand in the IR
* after `index` number of loads.
*/
class RawIndirectOperand extends Node, TRawIndirectOperand {
Operand operand;
int indirectionIndex;
private module RawIndirectNodes {
/**
* INTERNAL: Do not use.
*
* A node that represents the indirect value of an operand in the IR
* after `index` number of loads.
*/
private class RawIndirectOperand0 extends Node, TRawIndirectOperand0 {
Node0Impl node;
int indirectionIndex;
RawIndirectOperand() { this = TRawIndirectOperand(operand, indirectionIndex) }
RawIndirectOperand0() { this = TRawIndirectOperand0(node, indirectionIndex) }
/** Gets the underlying instruction. */
Operand getOperand() { result = operand }
/** Gets the underlying instruction. */
Operand getOperand() { result = node.asOperand() }
/** Gets the underlying indirection index. */
int getIndirectionIndex() { result = indirectionIndex }
/** Gets the underlying indirection index. */
int getIndirectionIndex() { result = indirectionIndex }
override Declaration getFunction() { result = this.getOperand().getDef().getEnclosingFunction() }
override Declaration getFunction() {
result = this.getOperand().getDef().getEnclosingFunction()
}
override Declaration getEnclosingCallable() { result = this.getFunction() }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowType getType() {
exists(int sub, DataFlowType type, boolean isGLValue |
type = getOperandType(operand, isGLValue) and
if isGLValue = true then sub = 1 else sub = 0
|
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
)
override DataFlowType getType() {
exists(int sub, DataFlowType type, boolean isGLValue |
type = getOperandType(this.getOperand(), isGLValue) and
if isGLValue = true then sub = 1 else sub = 0
|
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
)
}
final override Location getLocationImpl() {
if exists(this.getOperand().getLocation())
then result = this.getOperand().getLocation()
else result instanceof UnknownDefaultLocation
}
override string toStringImpl() {
result = operandNode(this.getOperand()).toStringImpl() + " indirection"
}
}
final override Location getLocationImpl() {
if exists(this.getOperand().getLocation())
then result = this.getOperand().getLocation()
else result instanceof UnknownDefaultLocation
/**
* INTERNAL: Do not use.
*
* A node that represents the indirect value of an instruction in the IR
* after `index` number of loads.
*/
private class RawIndirectInstruction0 extends Node, TRawIndirectInstruction0 {
Node0Impl node;
int indirectionIndex;
RawIndirectInstruction0() { this = TRawIndirectInstruction0(node, indirectionIndex) }
/** Gets the underlying instruction. */
Instruction getInstruction() { result = node.asInstruction() }
/** Gets the underlying indirection index. */
int getIndirectionIndex() { result = indirectionIndex }
override Declaration getFunction() { result = this.getInstruction().getEnclosingFunction() }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowType getType() {
exists(int sub, DataFlowType type, boolean isGLValue |
type = getInstructionType(this.getInstruction(), isGLValue) and
if isGLValue = true then sub = 1 else sub = 0
|
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
)
}
final override Location getLocationImpl() {
if exists(this.getInstruction().getLocation())
then result = this.getInstruction().getLocation()
else result instanceof UnknownDefaultLocation
}
override string toStringImpl() {
result = instructionNode(this.getInstruction()).toStringImpl() + " indirection"
}
}
override string toStringImpl() {
result = operandNode(this.getOperand()).toStringImpl() + " indirection"
/**
* INTERNAL: Do not use.
*
* A node that represents the indirect value of an operand in the IR
* after a number of loads.
*/
class RawIndirectOperand extends Node {
int indirectionIndex;
Operand operand;
RawIndirectOperand() {
exists(Node0Impl node | operand = node.asOperand() |
this = TRawIndirectOperand0(node, indirectionIndex)
or
this = TRawIndirectInstruction0(node, indirectionIndex)
)
}
/** Gets the operand associated with this node. */
Operand getOperand() { result = operand }
/** Gets the underlying indirection index. */
int getIndirectionIndex() { result = indirectionIndex }
}
/**
* INTERNAL: Do not use.
*
* A node that represents the indirect value of an instruction in the IR
* after a number of loads.
*/
class RawIndirectInstruction extends Node {
int indirectionIndex;
Instruction instr;
RawIndirectInstruction() {
exists(Node0Impl node | instr = node.asInstruction() |
this = TRawIndirectOperand0(node, indirectionIndex)
or
this = TRawIndirectInstruction0(node, indirectionIndex)
)
}
/** Gets the instruction associated with this node. */
Instruction getInstruction() { result = instr }
/** Gets the underlying indirection index. */
int getIndirectionIndex() { result = indirectionIndex }
}
}
import RawIndirectNodes
/**
* INTERNAL: do not use.
*
@@ -1021,48 +1100,6 @@ class UninitializedNode extends Node {
LocalVariable getLocalVariable() { result = v }
}
/**
* INTERNAL: Do not use.
*
* A node that represents the indirect value of an instruction in the IR
* after `index` number of loads.
*/
class RawIndirectInstruction extends Node, TRawIndirectInstruction {
Instruction instr;
int indirectionIndex;
RawIndirectInstruction() { this = TRawIndirectInstruction(instr, indirectionIndex) }
/** Gets the underlying instruction. */
Instruction getInstruction() { result = instr }
/** Gets the underlying indirection index. */
int getIndirectionIndex() { result = indirectionIndex }
override Declaration getFunction() { result = this.getInstruction().getEnclosingFunction() }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override DataFlowType getType() {
exists(int sub, DataFlowType type, boolean isGLValue |
type = getInstructionType(instr, isGLValue) and
if isGLValue = true then sub = 1 else sub = 0
|
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
)
}
final override Location getLocationImpl() {
if exists(this.getInstruction().getLocation())
then result = this.getInstruction().getLocation()
else result instanceof UnknownDefaultLocation
}
override string toStringImpl() {
result = instructionNode(this.getInstruction()).toStringImpl() + " indirection"
}
}
private module GetConvertedResultExpression {
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr
private import semmle.code.cpp.ir.implementation.raw.internal.InstructionTag
@@ -1600,26 +1637,29 @@ private module Cached {
predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFrom, nodeTo) }
private predicate indirectionOperandFlow(RawIndirectOperand nodeFrom, Node nodeTo) {
// Reduce the indirection count by 1 if we're passing through a `LoadInstruction`.
exists(int ind, LoadInstruction load |
hasOperandAndIndex(nodeFrom, load.getSourceAddressOperand(), ind) and
nodeHasInstruction(nodeTo, load, ind - 1)
)
or
// If an operand flows to an instruction, then the indirection of
// the operand also flows to the indirection of the instruction.
exists(Operand operand, Instruction instr, int indirectionIndex |
simpleInstructionLocalFlowStep(operand, instr) and
hasOperandAndIndex(nodeFrom, operand, pragma[only_bind_into](indirectionIndex)) and
hasInstructionAndIndex(nodeTo, instr, pragma[only_bind_into](indirectionIndex))
)
or
// If there's indirect flow to an operand, then there's also indirect
// flow to the operand after applying some pointer arithmetic.
exists(PointerArithmeticInstruction pointerArith, int indirectionIndex |
hasOperandAndIndex(nodeFrom, pointerArith.getAnOperand(),
pragma[only_bind_into](indirectionIndex)) and
hasInstructionAndIndex(nodeTo, pointerArith, pragma[only_bind_into](indirectionIndex))
nodeFrom != nodeTo and
(
// Reduce the indirection count by 1 if we're passing through a `LoadInstruction`.
exists(int ind, LoadInstruction load |
hasOperandAndIndex(nodeFrom, load.getSourceAddressOperand(), ind) and
nodeHasInstruction(nodeTo, load, ind - 1)
)
or
// If an operand flows to an instruction, then the indirection of
// the operand also flows to the indirection of the instruction.
exists(Operand operand, Instruction instr, int indirectionIndex |
simpleInstructionLocalFlowStep(operand, instr) and
hasOperandAndIndex(nodeFrom, operand, pragma[only_bind_into](indirectionIndex)) and
hasInstructionAndIndex(nodeTo, instr, pragma[only_bind_into](indirectionIndex))
)
or
// If there's indirect flow to an operand, then there's also indirect
// flow to the operand after applying some pointer arithmetic.
exists(PointerArithmeticInstruction pointerArith, int indirectionIndex |
hasOperandAndIndex(nodeFrom, pointerArith.getAnOperand(),
pragma[only_bind_into](indirectionIndex)) and
hasInstructionAndIndex(nodeTo, pointerArith, pragma[only_bind_into](indirectionIndex))
)
)
}
@@ -1645,6 +1685,7 @@ private module Cached {
private predicate indirectionInstructionFlow(
RawIndirectInstruction nodeFrom, IndirectOperand nodeTo
) {
nodeFrom != nodeTo and
// If there's flow from an instruction to an operand, then there's also flow from the
// indirect instruction to the indirect operand.
exists(Operand operand, Instruction instr, int indirectionIndex |

View File

@@ -113,22 +113,12 @@ private newtype TDefOrUseImpl =
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
// Represents a final "use" of a global variable to ensure that
// the assignment to a global variable isn't ruled out as dead.
exists(VariableAddressInstruction vai, int defIndex |
vai.getEnclosingIRFunction() = f and
vai.getAstVariable() = v and
isDef(_, _, _, vai, _, defIndex) and
indirectionIndex = [0 .. defIndex] + 1
)
isGlobalUse(v, f, _, indirectionIndex)
} or
TGlobalDefImpl(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
// Represents the initial "definition" of a global variable when entering
// a function body.
exists(VariableAddressInstruction vai |
vai.getEnclosingIRFunction() = f and
vai.getAstVariable() = v and
isUse(_, _, vai, _, indirectionIndex) and
not isDef(_, _, vai.getAUse(), _, _, _)
)
isGlobalDefImpl(v, f, _, indirectionIndex)
} or
TIteratorDef(
Operand iteratorDerefAddress, BaseSourceVariableInstruction container, int indirectionIndex
@@ -150,6 +140,27 @@ private newtype TDefOrUseImpl =
)
}
private predicate isGlobalUse(
GlobalLikeVariable v, IRFunction f, int indirection, int indirectionIndex
) {
exists(VariableAddressInstruction vai |
vai.getEnclosingIRFunction() = f and
vai.getAstVariable() = v and
isDef(_, _, _, vai, indirection, indirectionIndex)
)
}
private predicate isGlobalDefImpl(
GlobalLikeVariable v, IRFunction f, int indirection, int indirectionIndex
) {
exists(VariableAddressInstruction vai |
vai.getEnclosingIRFunction() = f and
vai.getAstVariable() = v and
isUse(_, _, vai, indirection, indirectionIndex) and
not isDef(_, _, _, vai, _, indirectionIndex)
)
}
private predicate unspecifiedTypeIsModifiableAt(Type unspecified, int indirectionIndex) {
indirectionIndex = [1 .. getIndirectionForUnspecifiedType(unspecified).getNumberOfIndirections()] and
exists(CppType cppType |
@@ -438,7 +449,7 @@ class GlobalUse extends UseImpl, TGlobalUse {
override FinalGlobalValue getNode() { result.getGlobalUse() = this }
override int getIndirection() { result = ind + 1 }
override int getIndirection() { isGlobalUse(global, f, result, ind) }
/** Gets the global variable associated with this use. */
GlobalLikeVariable getVariable() { result = global }
@@ -460,7 +471,9 @@ class GlobalUse extends UseImpl, TGlobalUse {
)
}
override SourceVariable getSourceVariable() { sourceVariableIsGlobal(result, global, f, ind) }
override SourceVariable getSourceVariable() {
sourceVariableIsGlobal(result, global, f, this.getIndirection())
}
final override Cpp::Location getLocation() { result = f.getLocation() }
@@ -501,16 +514,18 @@ class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl {
/** Gets the global variable associated with this definition. */
override SourceVariable getSourceVariable() {
sourceVariableIsGlobal(result, global, f, indirectionIndex)
sourceVariableIsGlobal(result, global, f, this.getIndirection())
}
int getIndirection() { result = indirectionIndex }
/**
* Gets the type of this use after specifiers have been deeply stripped
* and typedefs have been resolved.
*/
Type getUnspecifiedType() { result = global.getUnspecifiedType() }
override string toString() { result = "GlobalDef" }
override string toString() { result = "Def of " + this.getSourceVariable() }
override Location getLocation() { result = f.getLocation() }
@@ -980,7 +995,7 @@ class GlobalDef extends TGlobalDef, SsaDefOrUse {
final override Location getLocation() { result = global.getLocation() }
/** Gets a textual representation of this definition. */
override string toString() { result = "GlobalDef" }
override string toString() { result = global.toString() }
/**
* Holds if this definition has index `index` in block `block`, and
@@ -990,6 +1005,9 @@ class GlobalDef extends TGlobalDef, SsaDefOrUse {
global.hasIndexInBlock(block, index, sv)
}
/** Gets the indirection index of this definition. */
int getIndirection() { result = global.getIndirection() }
/** Gets the indirection index of this definition. */
int getIndirectionIndex() { result = global.getIndirectionIndex() }

View File

@@ -35,6 +35,7 @@ private import implementations.Accept
private import implementations.Poll
private import implementations.Select
private import implementations.MySql
private import implementations.ODBC
private import implementations.SqLite3
private import implementations.PostgreSql
private import implementations.System

View File

@@ -5,6 +5,7 @@
*/
import semmle.code.cpp.models.interfaces.Allocation
import semmle.code.cpp.models.interfaces.Taint
/**
* An allocation function (such as `malloc`) that has an argument for the size
@@ -121,7 +122,7 @@ private class CallocAllocationFunction extends AllocationFunction {
* An allocation function (such as `realloc`) that has an argument for the size
* in bytes, and an argument for an existing pointer that is to be reallocated.
*/
private class ReallocAllocationFunction extends AllocationFunction {
private class ReallocAllocationFunction extends AllocationFunction, TaintFunction {
int sizeArg;
int reallocArg;
@@ -151,6 +152,10 @@ private class ReallocAllocationFunction extends AllocationFunction {
override int getSizeArg() { result = sizeArg }
override int getReallocPtrArg() { result = reallocArg }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(this.getReallocPtrArg()) and output.isReturnValueDeref()
}
}
/**

View File

@@ -49,10 +49,11 @@ private class FgetsFunction extends DataFlowFunction, TaintFunction, ArrayFuncti
}
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
output.isParameterDeref(0) and
description = "string read by " + this.getName()
or
output.isReturnValue() and
(
output.isParameterDeref(0) or
output.isReturnValue() or
output.isReturnValueDeref()
) and
description = "string read by " + this.getName()
}

View File

@@ -157,7 +157,7 @@ private class Getaddrinfo extends TaintFunction, ArrayFunction, RemoteFlowSource
override predicate hasArrayWithNullTerminator(int bufParam) { bufParam in [0, 1] }
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
output.isParameterDeref(3) and
output.isParameterDeref(3, 2) and
description = "address returned by " + this.getName()
}
}

View File

@@ -9,18 +9,17 @@ import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect
/**
* The standard function `memset` and its assorted variants
*/
private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunction,
private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, AliasFunction,
SideEffectFunction
{
MemsetFunction() {
MemsetFunctionModel() {
this.hasGlobalOrStdOrBslName("memset")
or
this.hasGlobalOrStdName("wmemset")
or
this.hasGlobalName([bzero(), "__builtin_memset", "__builtin_memset_chk"])
this.hasGlobalName([
bzero(), "__builtin_memset", "__builtin_memset_chk", "RtlZeroMemory", "RtlSecureZeroMemory"
])
}
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
@@ -60,3 +59,8 @@ private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunct
}
private string bzero() { result = ["bzero", "explicit_bzero"] }
/**
* The standard function `memset` and its assorted variants
*/
class MemsetFunction extends Function instanceof MemsetFunctionModel { }

View File

@@ -0,0 +1,28 @@
/**
* Provides implementation classes modeling the ODBC C/C++ API.
* See `semmle.code.cpp.models.Models` for usage information.
*/
private import semmle.code.cpp.models.interfaces.Sql
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
/**
* The `SQLExecDirect`, and `SQLPrepare` from the ODBC C/C++ API:
* https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlexecdirect-function?view=sql-server-ver16
* https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprepare-function?view=sql-server-ver16
*
* Note, `SQLExecute` is not included because it operates on a SQLHSTMT type, not a string.
* The SQLHSTMT parameter for `SQLExecute` is set through a `SQLPrepare`, which is modeled.
* The other source of input to a `SQLExecute` is via a `SQLBindParameter`, which sanitizes user input,
* and would be considered a barrier to SQL injection.
*/
private class ODBCExecutionFunction extends SqlExecutionFunction {
ODBCExecutionFunction() { this.hasGlobalName(["SQLExecDirect", "SQLPrepare"]) }
override predicate hasSqlArgument(FunctionInput input) { input.isParameterDeref(1) }
}
// NOTE: no need to define a barrier explicitly.
// `SQLBindParameter` is the typical means for sanitizing user input.
// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbindparameter-function?view=sql-server-ver16
// First a query is establisehed via `SQLPrepare`, then parameters are bound via `SQLBindParameter`, before
// the query is executed via `SQLExecute`. We are not modeling SQLExecute, so we do not need to model SQLBindParameter.

View File

@@ -147,19 +147,32 @@ private class SnprintfImpl extends Snprintf {
/**
* The Microsoft `StringCchPrintf` function and variants.
* See: https://learn.microsoft.com/en-us/windows/win32/api/strsafe/
* and
* https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms860435(v=msdn.10)
*/
private class StringCchPrintf extends FormattingFunction {
StringCchPrintf() {
this instanceof TopLevelFunction and
this.hasGlobalName([
"StringCchPrintf", "StringCchPrintfEx", "StringCchPrintf_l", "StringCchPrintf_lEx",
"StringCbPrintf", "StringCbPrintfEx", "StringCbPrintf_l", "StringCbPrintf_lEx"
]) and
exists(string baseName |
baseName in [
"StringCchPrintf", //StringCchPrintf(pszDest, cchDest, pszFormat, ...)
"StringCchPrintfEx", //StringCchPrintfEx(pszDest,cchDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, ...)
"StringCchPrintf_l", //StringCchPrintf_l(pszDest, cbDest, pszFormat, locale, ...)
"StringCchPrintf_lEx", //StringCchPrintf_lEx(pszDest, cchDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, locale, ...)
"StringCbPrintf", //StringCbPrintf(pszDest, cbDest, pszFormat, ...)
"StringCbPrintfEx", //StringCbPrintfEx(pszDest, cbDest, ppszDestEnd, pcbRemaining, dwFlags, pszFormat, ...)
"StringCbPrintf_l", //StringCbPrintf_l(pszDest, cbDest, pszFormat, locale, ...)
"StringCbPrintf_lEx" //StringCbPrintf_lEx(pszDest, cbDest, ppszDestEnd, pcbRemaining, dwFlags, pszFormat, locale, ...)
]
|
this.hasGlobalName(baseName + ["", "A", "W"])
) and
not exists(this.getDefinition().getFile().getRelativePath())
}
override int getFormatParameterIndex() {
if this.getName().matches("%Ex") then result = 5 else result = 2
if this.getName().matches("%Ex" + ["", "A", "W"]) then result = 5 else result = 2
}
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = false }

View File

@@ -58,7 +58,7 @@ private class Send extends AliasFunction, ArrayFunction, SideEffectFunction, Rem
override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 1 and result = 2 }
override predicate hasRemoteFlowSink(FunctionInput input, string description) {
input.isParameterDeref(1) and description = "buffer sent by " + this.getName()
input.isParameterDeref(1, 1) and description = "buffer sent by " + this.getName()
}
override predicate hasSocketInput(FunctionInput input) { input.isParameter(0) }

View File

@@ -10,6 +10,8 @@ import semmle.code.cpp.models.interfaces.SideEffect
/**
* The standard function `strcat` and its wide, sized, and Microsoft variants.
*
* Does not include `strlcat`, which is covered by `StrlcatFunction`
*/
class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction {
StrcatFunction() {
@@ -90,3 +92,64 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
buffer = true
}
}
/**
* The `strlcat` function.
*/
class StrlcatFunction extends TaintFunction, ArrayFunction, SideEffectFunction {
StrlcatFunction() {
this.hasGlobalName("strlcat") // strlcat(dst, src, dst_size)
}
/**
* Gets the index of the parameter that is the size of the copy (in characters).
*/
int getParamSize() { result = 2 }
/**
* Gets the index of the parameter that is the source of the copy.
*/
int getParamSrc() { result = 1 }
/**
* Gets the index of the parameter that is the destination to be appended to.
*/
int getParamDest() { result = 0 }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
(
input.isParameter(2)
or
input.isParameterDeref(0)
or
input.isParameterDeref(1)
) and
output.isParameterDeref(0)
}
override predicate hasArrayInput(int param) {
param = 0 or
param = 1
}
override predicate hasArrayOutput(int param) { param = 0 }
override predicate hasArrayWithNullTerminator(int param) { param = 1 }
override predicate hasArrayWithUnknownSize(int param) { param = 0 }
override predicate hasOnlySpecificReadSideEffects() { any() }
override predicate hasOnlySpecificWriteSideEffects() { any() }
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
i = 0 and
buffer = true and
mustWrite = false
}
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
(i = 0 or i = 1) and
buffer = true
}
}

View File

@@ -32,7 +32,8 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
"wcsxfrm_l", // _strxfrm_l(dest, src, max_amount, locale)
"_mbsnbcpy", // _mbsnbcpy(dest, src, max_amount)
"stpcpy", // stpcpy(dest, src)
"stpncpy" // stpcpy(dest, src, max_amount)
"stpncpy", // stpncpy(dest, src, max_amount)
"strlcpy" // strlcpy(dst, src, dst_size)
])
or
(
@@ -53,6 +54,11 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
*/
private predicate isSVariant() { this.getName().matches("%\\_s") }
/**
* Holds if the function returns the total length the string would have had if the size was unlimited.
*/
private predicate returnsTotalLength() { this.getName() = "strlcpy" }
/**
* Gets the index of the parameter that is the maximum size of the copy (in characters).
*/
@@ -60,7 +66,7 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
if this.isSVariant()
then result = 1
else (
this.getName().matches(["%ncpy%", "%nbcpy%", "%xfrm%"]) and
this.getName().matches(["%ncpy%", "%nbcpy%", "%xfrm%", "strlcpy"]) and
result = 2
)
}
@@ -100,6 +106,7 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
input.isParameterDeref(this.getParamSrc()) and
output.isReturnValueDeref()
or
not this.returnsTotalLength() and
input.isParameter(this.getParamDest()) and
output.isReturnValue()
}
@@ -110,8 +117,9 @@ class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, Sid
exists(this.getParamSize()) and
input.isParameterDeref(this.getParamSrc()) and
(
output.isParameterDeref(this.getParamDest()) or
output.isReturnValueDeref()
output.isParameterDeref(this.getParamDest())
or
not this.returnsTotalLength() and output.isReturnValueDeref()
)
}

View File

@@ -8,7 +8,7 @@ import semmle.code.cpp.Parameter
private newtype TFunctionInput =
TInParameter(ParameterIndex i) or
TInParameterDeref(ParameterIndex i) or
TInParameterDeref(ParameterIndex i, int indirectionIndex) { indirectionIndex = [1, 2] } or
TInQualifierObject() or
TInQualifierAddress() or
TInReturnValueDeref()
@@ -245,15 +245,18 @@ class InParameter extends FunctionInput, TInParameter {
*/
class InParameterDeref extends FunctionInput, TInParameterDeref {
ParameterIndex index;
int indirectionIndex;
InParameterDeref() { this = TInParameterDeref(index) }
InParameterDeref() { this = TInParameterDeref(index, indirectionIndex) }
override string toString() { result = "InParameterDeref " + index.toString() }
/** Gets the zero-based index of the parameter. */
ParameterIndex getIndex() { result = index }
override predicate isParameterDeref(ParameterIndex i) { i = index }
override predicate isParameterDeref(ParameterIndex i, int indirection) {
i = index and indirectionIndex = indirection
}
}
/**
@@ -321,10 +324,10 @@ class InReturnValueDeref extends FunctionInput, TInReturnValueDeref {
}
private newtype TFunctionOutput =
TOutParameterDeref(ParameterIndex i) or
TOutParameterDeref(ParameterIndex i, int indirectionIndex) { indirectionIndex = [1, 2] } or
TOutQualifierObject() or
TOutReturnValue() or
TOutReturnValueDeref()
TOutReturnValueDeref(int indirections) { indirections = [1, 2] }
/**
* An output from a function. This can be:
@@ -498,17 +501,16 @@ class FunctionOutput extends TFunctionOutput {
*/
class OutParameterDeref extends FunctionOutput, TOutParameterDeref {
ParameterIndex index;
int indirectionIndex;
OutParameterDeref() { this = TOutParameterDeref(index) }
OutParameterDeref() { this = TOutParameterDeref(index, indirectionIndex) }
override string toString() { result = "OutParameterDeref " + index.toString() }
ParameterIndex getIndex() { result = index }
override predicate isParameterDeref(ParameterIndex i) { i = index }
override predicate isParameterDeref(ParameterIndex i, int ind) {
this.isParameterDeref(i) and ind = 1
i = index and ind = indirectionIndex
}
}
@@ -572,4 +574,8 @@ class OutReturnValueDeref extends FunctionOutput, TOutReturnValueDeref {
override string toString() { result = "OutReturnValueDeref" }
override predicate isReturnValueDeref() { any() }
override predicate isReturnValueDeref(int indirectionIndex) {
this = TOutReturnValueDeref(indirectionIndex)
}
}

View File

@@ -17,9 +17,7 @@ private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
* `upper` is true, and can be traced back to a guard represented by `reason`.
*/
predicate bounded(Expr e, Bound b, float delta, boolean upper, Reason reason) {
exists(SemanticExprConfig::Expr semExpr |
semExpr.getUnconverted().getUnconvertedResultExpression() = e
|
exists(SemanticExprConfig::Expr semExpr | semExpr.getUnconvertedResultExpression() = e |
semBounded(semExpr, b, delta, upper, reason)
)
}
@@ -30,9 +28,7 @@ predicate bounded(Expr e, Bound b, float delta, boolean upper, Reason reason) {
* The `Expr` may be a conversion.
*/
predicate convertedBounded(Expr e, Bound b, float delta, boolean upper, Reason reason) {
exists(SemanticExprConfig::Expr semExpr |
semExpr.getConverted().getConvertedResultExpression() = e
|
exists(SemanticExprConfig::Expr semExpr | semExpr.getConvertedResultExpression() = e |
semBounded(semExpr, b, delta, upper, reason)
)
}

View File

@@ -100,7 +100,7 @@ predicate exprMightOverflowNegatively(Expr expr) {
lowerBound(expr) < exprMinVal(expr)
or
exists(SemanticExprConfig::Expr semExpr |
semExpr.getUnconverted().getAst() = expr and
semExpr.getAst() = expr and
ConstantStage::potentiallyOverflowingExpr(false, semExpr) and
not ConstantStage::initialBounded(semExpr, _, _, false, _, _, _)
)
@@ -126,7 +126,7 @@ predicate exprMightOverflowPositively(Expr expr) {
upperBound(expr) > exprMaxVal(expr)
or
exists(SemanticExprConfig::Expr semExpr |
semExpr.getUnconverted().getAst() = expr and
semExpr.getAst() = expr and
ConstantStage::potentiallyOverflowingExpr(true, semExpr) and
not ConstantStage::initialBounded(semExpr, _, _, true, _, _, _)
)

View File

@@ -12,9 +12,6 @@ class SemBasicBlock extends Specific::BasicBlock {
/** Holds if this block (transitively) dominates `otherblock`. */
final predicate bbDominates(SemBasicBlock otherBlock) { Specific::bbDominates(this, otherBlock) }
/** Holds if this block has dominance information. */
final predicate hasDominanceInformation() { Specific::hasDominanceInformation(this) }
/** Gets an expression that is evaluated in this basic block. */
final SemExpr getAnExpr() { result.getBasicBlock() = this }

View File

@@ -4,6 +4,7 @@
private import Semantic
private import SemanticExprSpecific::SemanticExprConfig as Specific
private import SemanticType
/**
* An language-neutral expression.
@@ -241,8 +242,21 @@ class SemConvertExpr extends SemUnaryExpr {
SemConvertExpr() { opcode instanceof Opcode::Convert }
}
private import semmle.code.cpp.ir.IR as IR
/** A conversion instruction which is guaranteed to not overflow. */
private class SafeConversion extends IR::ConvertInstruction {
SafeConversion() {
exists(SemType tFrom, SemType tTo |
tFrom = getSemanticType(super.getUnary().getResultIRType()) and
tTo = getSemanticType(super.getResultIRType()) and
conversionCannotOverflow(tFrom, tTo)
)
}
}
class SemCopyValueExpr extends SemUnaryExpr {
SemCopyValueExpr() { opcode instanceof Opcode::CopyValue }
SemCopyValueExpr() { opcode instanceof Opcode::CopyValue or this instanceof SafeConversion }
}
class SemNegateExpr extends SemUnaryExpr {

View File

@@ -12,87 +12,10 @@ private import semmle.code.cpp.ir.ValueNumbering
module SemanticExprConfig {
class Location = Cpp::Location;
/** A `ConvertInstruction` or a `CopyValueInstruction`. */
private class Conversion extends IR::UnaryInstruction {
Conversion() {
this instanceof IR::CopyValueInstruction
or
this instanceof IR::ConvertInstruction
}
/** Holds if this instruction converts a value of type `tFrom` to a value of type `tTo`. */
predicate converts(SemType tFrom, SemType tTo) {
tFrom = getSemanticType(this.getUnary().getResultIRType()) and
tTo = getSemanticType(this.getResultIRType())
}
}
/**
* Gets a conversion-like instruction that consumes `op`, and
* which is guaranteed to not overflow.
*/
private IR::Instruction safeConversion(IR::Operand op) {
exists(Conversion conv, SemType tFrom, SemType tTo |
conv.converts(tFrom, tTo) and
conversionCannotOverflow(tFrom, tTo) and
conv.getUnaryOperand() = op and
result = conv
)
}
/** Holds if `i1 = i2` or if `i2` is a safe conversion that consumes `i1`. */
private predicate idOrSafeConversion(IR::Instruction i1, IR::Instruction i2) {
not i1.getResultIRType() instanceof IR::IRVoidType and
(
i1 = i2
or
i2 = safeConversion(i1.getAUse()) and
i1.getBlock() = i2.getBlock()
)
}
module Equiv = QlBuiltins::EquivalenceRelation<IR::Instruction, idOrSafeConversion/2>;
/**
* The expressions on which we perform range analysis.
*/
class Expr extends Equiv::EquivalenceClass {
/** Gets the n'th instruction in this equivalence class. */
private IR::Instruction getInstruction(int n) {
result =
rank[n + 1](IR::Instruction instr, int i, IR::IRBlock block |
this = Equiv::getEquivalenceClass(instr) and block.getInstruction(i) = instr
|
instr order by i
)
}
/** Gets a textual representation of this element. */
string toString() { result = this.getUnconverted().toString() }
/** Gets the basic block of this expression. */
IR::IRBlock getBlock() { result = this.getUnconverted().getBlock() }
/** Gets the unconverted instruction associated with this expression. */
IR::Instruction getUnconverted() { result = this.getInstruction(0) }
/**
* Gets the final instruction associated with this expression. This
* represents the result after applying all the safe conversions.
*/
IR::Instruction getConverted() {
exists(int n |
result = this.getInstruction(n) and
not exists(this.getInstruction(n + 1))
)
}
/** Gets the type of the result produced by this instruction. */
IR::IRType getResultIRType() { result = this.getConverted().getResultIRType() }
/** Gets the location of the source code for this expression. */
Location getLocation() { result = this.getUnconverted().getLocation() }
}
class Expr = IR::Instruction;
SemBasicBlock getExprBasicBlock(Expr e) { result = getSemanticBasicBlock(e.getBlock()) }
@@ -139,12 +62,12 @@ module SemanticExprConfig {
predicate stringLiteral(Expr expr, SemType type, string value) {
anyConstantExpr(expr, type, value) and
expr.getUnconverted() instanceof IR::StringConstantInstruction
expr instanceof IR::StringConstantInstruction
}
predicate binaryExpr(Expr expr, Opcode opcode, SemType type, Expr leftOperand, Expr rightOperand) {
exists(IR::BinaryInstruction instr |
instr = expr.getUnconverted() and
instr = expr and
type = getSemanticType(instr.getResultIRType()) and
leftOperand = getSemanticExpr(instr.getLeft()) and
rightOperand = getSemanticExpr(instr.getRight()) and
@@ -154,14 +77,14 @@ module SemanticExprConfig {
}
predicate unaryExpr(Expr expr, Opcode opcode, SemType type, Expr operand) {
exists(IR::UnaryInstruction instr | instr = expr.getUnconverted() |
exists(IR::UnaryInstruction instr | instr = expr |
type = getSemanticType(instr.getResultIRType()) and
operand = getSemanticExpr(instr.getUnary()) and
// REVIEW: Merge the two operand types.
opcode.toString() = instr.getOpcode().toString()
)
or
exists(IR::StoreInstruction instr | instr = expr.getUnconverted() |
exists(IR::StoreInstruction instr | instr = expr |
type = getSemanticType(instr.getResultIRType()) and
operand = getSemanticExpr(instr.getSourceValue()) and
opcode instanceof Opcode::Store
@@ -170,13 +93,13 @@ module SemanticExprConfig {
predicate nullaryExpr(Expr expr, Opcode opcode, SemType type) {
exists(IR::LoadInstruction load |
load = expr.getUnconverted() and
load = expr and
type = getSemanticType(load.getResultIRType()) and
opcode instanceof Opcode::Load
)
or
exists(IR::InitializeParameterInstruction init |
init = expr.getUnconverted() and
init = expr and
type = getSemanticType(init.getResultIRType()) and
opcode instanceof Opcode::InitializeParameter
)
@@ -199,8 +122,6 @@ module SemanticExprConfig {
dominator.dominates(dominated)
}
predicate hasDominanceInformation(BasicBlock block) { any() }
private predicate id(Cpp::Locatable x, Cpp::Locatable y) { x = y }
private predicate idOf(Cpp::Locatable x, int y) = equivalenceRelation(id/2)(x, y)
@@ -209,17 +130,7 @@ module SemanticExprConfig {
newtype TSsaVariable =
TSsaInstruction(IR::Instruction instr) { instr.hasMemoryResult() } or
TSsaOperand(IR::Operand op) { op.isDefinitionInexact() } or
TSsaPointerArithmeticGuard(ValueNumber instr) {
exists(Guard g, IR::Operand use |
use = instr.getAUse() and use.getIRType() instanceof IR::IRAddressType
|
g.comparesLt(use, _, _, _, _) or
g.comparesLt(_, use, _, _, _) or
g.comparesEq(use, _, _, _, _) or
g.comparesEq(_, use, _, _, _)
)
}
TSsaOperand(IR::PhiInputOperand op) { op.isDefinitionInexact() }
class SsaVariable extends TSsaVariable {
string toString() { none() }
@@ -228,9 +139,7 @@ module SemanticExprConfig {
IR::Instruction asInstruction() { none() }
ValueNumber asPointerArithGuard() { none() }
IR::Operand asOperand() { none() }
IR::PhiInputOperand asOperand() { none() }
}
class SsaInstructionVariable extends SsaVariable, TSsaInstruction {
@@ -245,20 +154,8 @@ module SemanticExprConfig {
final override IR::Instruction asInstruction() { result = instr }
}
class SsaPointerArithmeticGuard extends SsaVariable, TSsaPointerArithmeticGuard {
ValueNumber vn;
SsaPointerArithmeticGuard() { this = TSsaPointerArithmeticGuard(vn) }
final override string toString() { result = vn.toString() }
final override Location getLocation() { result = vn.getLocation() }
final override ValueNumber asPointerArithGuard() { result = vn }
}
class SsaOperand extends SsaVariable, TSsaOperand {
IR::Operand op;
IR::PhiInputOperand op;
SsaOperand() { this = TSsaOperand(op) }
@@ -266,7 +163,7 @@ module SemanticExprConfig {
final override Location getLocation() { result = op.getLocation() }
final override IR::Operand asOperand() { result = op }
final override IR::PhiInputOperand asOperand() { result = op }
}
predicate explicitUpdate(SsaVariable v, Expr sourceExpr) {
@@ -289,97 +186,29 @@ module SemanticExprConfig {
)
}
Expr getAUse(SsaVariable v) {
result.getUnconverted().(IR::LoadInstruction).getSourceValue() = v.asInstruction()
or
result.getUnconverted() = v.asPointerArithGuard().getAnInstruction()
}
Expr getAUse(SsaVariable v) { result.(IR::LoadInstruction).getSourceValue() = v.asInstruction() }
SemType getSsaVariableType(SsaVariable v) {
result = getSemanticType(v.asInstruction().getResultIRType())
or
result = getSemanticType(v.asOperand().getUse().getResultIRType())
}
BasicBlock getSsaVariableBasicBlock(SsaVariable v) {
result = v.asInstruction().getBlock()
or
result = v.asOperand().getUse().getBlock()
result = v.asOperand().getAnyDef().getBlock()
}
private newtype TReadPosition =
TReadPositionBlock(IR::IRBlock block) or
TReadPositionPhiInputEdge(IR::IRBlock pred, IR::IRBlock succ) {
exists(IR::PhiInputOperand input |
pred = input.getPredecessorBlock() and
succ = input.getUse().getBlock()
)
}
class SsaReadPosition extends TReadPosition {
string toString() { none() }
Location getLocation() { none() }
predicate hasRead(SsaVariable v) { none() }
}
private class SsaReadPositionBlock extends SsaReadPosition, TReadPositionBlock {
IR::IRBlock block;
SsaReadPositionBlock() { this = TReadPositionBlock(block) }
final override string toString() { result = block.toString() }
final override Location getLocation() { result = block.getLocation() }
final override predicate hasRead(SsaVariable v) {
exists(IR::Operand operand |
operand.getDef() = v.asInstruction() or
operand.getDef() = v.asPointerArithGuard().getAnInstruction()
|
not operand instanceof IR::PhiInputOperand and
operand.getUse().getBlock() = block
)
}
}
private class SsaReadPositionPhiInputEdge extends SsaReadPosition, TReadPositionPhiInputEdge {
IR::IRBlock pred;
IR::IRBlock succ;
SsaReadPositionPhiInputEdge() { this = TReadPositionPhiInputEdge(pred, succ) }
final override string toString() { result = pred.toString() + "->" + succ.toString() }
final override Location getLocation() { result = succ.getLocation() }
final override predicate hasRead(SsaVariable v) {
exists(IR::PhiInputOperand operand |
operand.getDef() = v.asInstruction() or
operand.getDef() = v.asPointerArithGuard().getAnInstruction()
|
operand.getPredecessorBlock() = pred and
operand.getUse().getBlock() = succ
)
}
}
predicate hasReadOfSsaVariable(SsaReadPosition pos, SsaVariable v) { pos.hasRead(v) }
predicate readBlock(SsaReadPosition pos, BasicBlock block) { pos = TReadPositionBlock(block) }
predicate phiInputEdge(SsaReadPosition pos, BasicBlock origBlock, BasicBlock phiBlock) {
pos = TReadPositionPhiInputEdge(origBlock, phiBlock)
}
predicate phiInput(SsaReadPosition pos, SsaVariable phi, SsaVariable input) {
/** Holds if `inp` is an input to the phi node along the edge originating in `bb`. */
predicate phiInputFromBlock(SsaVariable phi, SsaVariable inp, BasicBlock bb) {
exists(IR::PhiInputOperand operand |
pos = TReadPositionPhiInputEdge(operand.getPredecessorBlock(), operand.getUse().getBlock())
|
bb = operand.getPredecessorBlock() and
phi.asInstruction() = operand.getUse() and
(
input.asInstruction() = operand.getDef()
inp.asInstruction() = operand.getDef()
or
input.asOperand() = operand
inp.asOperand() = operand
)
)
}
@@ -433,7 +262,7 @@ module SemanticExprConfig {
}
/** Gets the expression associated with `instr`. */
SemExpr getSemanticExpr(IR::Instruction instr) { result = Equiv::getEquivalenceClass(instr) }
SemExpr getSemanticExpr(IR::Instruction instr) { result = instr }
}
predicate getSemanticExpr = SemanticExprConfig::getSemanticExpr/1;

View File

@@ -35,32 +35,4 @@ predicate semImplies_v2(SemGuard g1, boolean b1, SemGuard g2, boolean b2) {
Specific::implies_v2(g1, b1, g2, b2)
}
/**
* Holds if `guard` directly controls the position `controlled` with the
* value `testIsTrue`.
*/
pragma[nomagic]
predicate semGuardDirectlyControlsSsaRead(
SemGuard guard, SemSsaReadPosition controlled, boolean testIsTrue
) {
guard.directlyControls(controlled.(SemSsaReadPositionBlock).getBlock(), testIsTrue)
or
exists(SemSsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
guard.directlyControls(controlledEdge.getOrigBlock(), testIsTrue) or
guard.hasBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(), testIsTrue)
)
}
/**
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
*/
predicate semGuardControlsSsaRead(SemGuard guard, SemSsaReadPosition controlled, boolean testIsTrue) {
semGuardDirectlyControlsSsaRead(guard, controlled, testIsTrue)
or
exists(SemGuard guard0, boolean testIsTrue0 |
semImplies_v2(guard0, testIsTrue0, guard, testIsTrue) and
semGuardControlsSsaRead(guard0, controlled, testIsTrue0)
)
}
SemGuard semGetComparisonGuard(SemRelationalExpr e) { result = Specific::comparisonGuard(e) }

View File

@@ -22,75 +22,15 @@ class SemSsaExplicitUpdate extends SemSsaVariable {
SemSsaExplicitUpdate() { Specific::explicitUpdate(this, sourceExpr) }
final SemExpr getSourceExpr() { result = sourceExpr }
final SemExpr getDefiningExpr() { result = sourceExpr }
}
class SemSsaPhiNode extends SemSsaVariable {
SemSsaPhiNode() { Specific::phi(this) }
final SemSsaVariable getAPhiInput() { result = Specific::getAPhiInput(this) }
}
class SemSsaReadPosition instanceof Specific::SsaReadPosition {
final string toString() { result = super.toString() }
final Specific::Location getLocation() { result = super.getLocation() }
final predicate hasReadOfVar(SemSsaVariable var) { Specific::hasReadOfSsaVariable(this, var) }
}
class SemSsaReadPositionPhiInputEdge extends SemSsaReadPosition {
SemBasicBlock origBlock;
SemBasicBlock phiBlock;
SemSsaReadPositionPhiInputEdge() { Specific::phiInputEdge(this, origBlock, phiBlock) }
predicate phiInput(SemSsaPhiNode phi, SemSsaVariable inp) { Specific::phiInput(this, phi, inp) }
SemBasicBlock getOrigBlock() { result = origBlock }
SemBasicBlock getPhiBlock() { result = phiBlock }
}
class SemSsaReadPositionBlock extends SemSsaReadPosition {
SemBasicBlock block;
SemSsaReadPositionBlock() { Specific::readBlock(this, block) }
SemBasicBlock getBlock() { result = block }
SemExpr getAnExpr() { result = this.getBlock().getAnExpr() }
}
/**
* Holds if `inp` is an input to `phi` along a back edge.
*/
predicate semBackEdge(SemSsaPhiNode phi, SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge) {
edge.phiInput(phi, inp) and
// Conservatively assume that every edge is a back edge if we don't have dominance information.
(
phi.getBasicBlock().bbDominates(edge.getOrigBlock()) or
irreducibleSccEdge(edge.getOrigBlock(), phi.getBasicBlock()) or
not edge.getOrigBlock().hasDominanceInformation()
)
}
/**
* Holds if the edge from b1 to b2 is part of a multiple-entry cycle in an irreducible control flow
* graph.
*
* An ireducible control flow graph is one where the usual dominance-based back edge detection does
* not work, because there is a cycle with multiple entry points, meaning there are
* mutually-reachable basic blocks where neither dominates the other. For such a graph, we first
* remove all detectable back-edges using the normal condition that the predecessor block is
* dominated by the successor block, then mark all edges in a cycle in the resulting graph as back
* edges.
*/
private predicate irreducibleSccEdge(SemBasicBlock b1, SemBasicBlock b2) {
trimmedEdge(b1, b2) and trimmedEdge+(b2, b1)
}
private predicate trimmedEdge(SemBasicBlock pred, SemBasicBlock succ) {
pred.getASuccessor() = succ and
not succ.bbDominates(pred)
final predicate hasInputFromBlock(SemSsaVariable inp, SemBasicBlock bb) {
Specific::phiInputFromBlock(this, inp, bb)
}
}

View File

@@ -14,7 +14,7 @@ private predicate constantIntegerExpr(SemExpr e, int val) {
// Copy of another constant
exists(SemSsaExplicitUpdate v, SemExpr src |
e = v.getAUse() and
src = v.getSourceExpr() and
src = v.getDefiningExpr() and
constantIntegerExpr(src, val)
)
or

View File

@@ -1,328 +0,0 @@
/**
* Provides inferences of the form: `e` equals `b + v` modulo `m` where `e` is
* an expression, `b` is a `Bound` (typically zero or the value of an SSA
* variable), and `v` is an integer in the range `[0 .. m-1]`.
*/
/*
* The main recursion has base cases in both `ssaModulus` (for guarded reads) and `semExprModulus`
* (for constant values). The most interesting recursive case is `phiModulusRankStep`, which
* handles phi inputs.
*/
private import ModulusAnalysisSpecific::Private
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticLocation
private import ConstantAnalysis
private import RangeUtils
private import codeql.rangeanalysis.RangeAnalysis
private import RangeAnalysisImpl
module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig<Sem, D> U> {
pragma[nomagic]
private predicate valueFlowStepSsaEqFlowCond(
SemSsaReadPosition pos, SemSsaVariable v, SemExpr e, int delta
) {
exists(SemGuard guard, boolean testIsTrue |
guard = U::semEqFlowCond(v, e, D::fromInt(delta), true, testIsTrue) and
semGuardDirectlyControlsSsaRead(guard, pos, testIsTrue)
)
}
/**
* Holds if `e + delta` equals `v` at `pos`.
*/
pragma[nomagic]
private predicate valueFlowStepSsa(SemSsaVariable v, SemSsaReadPosition pos, SemExpr e, int delta) {
U::semSsaUpdateStep(v, e, D::fromInt(delta)) and pos.hasReadOfVar(v)
or
pos.hasReadOfVar(v) and
valueFlowStepSsaEqFlowCond(pos, v, e, delta)
}
/**
* Holds if `add` is the addition of `larg` and `rarg`, neither of which are
* `ConstantIntegerExpr`s.
*/
private predicate nonConstAddition(SemExpr add, SemExpr larg, SemExpr rarg) {
exists(SemAddExpr a | a = add |
larg = a.getLeftOperand() and
rarg = a.getRightOperand()
) and
not larg instanceof SemConstantIntegerExpr and
not rarg instanceof SemConstantIntegerExpr
}
/**
* Holds if `sub` is the subtraction of `larg` and `rarg`, where `rarg` is not
* a `ConstantIntegerExpr`.
*/
private predicate nonConstSubtraction(SemExpr sub, SemExpr larg, SemExpr rarg) {
exists(SemSubExpr s | s = sub |
larg = s.getLeftOperand() and
rarg = s.getRightOperand()
) and
not rarg instanceof SemConstantIntegerExpr
}
/** Gets an expression that is the remainder modulo `mod` of `arg`. */
private SemExpr modExpr(SemExpr arg, int mod) {
exists(SemRemExpr rem |
result = rem and
arg = rem.getLeftOperand() and
rem.getRightOperand().(SemConstantIntegerExpr).getIntValue() = mod and
mod >= 2
)
or
exists(SemConstantIntegerExpr c |
mod = 2.pow([1 .. 30]) and
c.getIntValue() = mod - 1 and
result.(SemBitAndExpr).hasOperands(arg, c)
)
}
/**
* Gets a guard that tests whether `v` is congruent with `val` modulo `mod` on
* its `testIsTrue` branch.
*/
private SemGuard moduloCheck(SemSsaVariable v, int val, int mod, boolean testIsTrue) {
exists(SemExpr rem, SemConstantIntegerExpr c, int r, boolean polarity |
result.isEquality(rem, c, polarity) and
c.getIntValue() = r and
rem = modExpr(v.getAUse(), mod) and
(
testIsTrue = polarity and val = r
or
testIsTrue = polarity.booleanNot() and
mod = 2 and
val = 1 - r and
(r = 0 or r = 1)
)
)
}
/**
* Holds if a guard ensures that `v` at `pos` is congruent with `val` modulo `mod`.
*/
private predicate moduloGuardedRead(SemSsaVariable v, SemSsaReadPosition pos, int val, int mod) {
exists(SemGuard guard, boolean testIsTrue |
pos.hasReadOfVar(v) and
guard = moduloCheck(v, val, mod, testIsTrue) and
semGuardControlsSsaRead(guard, pos, testIsTrue)
)
}
/** Holds if `factor` is a power of 2 that divides `mask`. */
bindingset[mask]
private predicate andmaskFactor(int mask, int factor) {
mask % factor = 0 and
factor = 2.pow([1 .. 30])
}
/** Holds if `e` is evenly divisible by `factor`. */
private predicate evenlyDivisibleExpr(SemExpr e, int factor) {
exists(SemConstantIntegerExpr c, int k | k = c.getIntValue() |
e.(SemMulExpr).getAnOperand() = c and factor = k.abs() and factor >= 2
or
e.(SemShiftLeftExpr).getRightOperand() = c and factor = 2.pow(k) and k > 0
or
e.(SemBitAndExpr).getAnOperand() = c and factor = max(int f | andmaskFactor(k, f))
)
}
/**
* Gets the remainder of `val` modulo `mod`.
*
* For `mod = 0` the result equals `val` and for `mod > 1` the result is within
* the range `[0 .. mod-1]`.
*/
bindingset[val, mod]
private int remainder(int val, int mod) {
mod = 0 and result = val
or
mod > 1 and result = ((val % mod) + mod) % mod
}
/**
* Holds if `inp` is an input to `phi` and equals `phi` modulo `mod` along `edge`.
*/
private predicate phiSelfModulus(
SemSsaPhiNode phi, SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge, int mod
) {
exists(Bounds::SemSsaBound phibound, int v, int m |
edge.phiInput(phi, inp) and
phibound.getAVariable() = phi and
ssaModulus(inp, edge, phibound, v, m) and
mod = m.gcd(v) and
mod != 1
)
}
/**
* Holds if `b + val` modulo `mod` is a candidate congruence class for `phi`.
*/
private predicate phiModulusInit(SemSsaPhiNode phi, Bounds::SemBound b, int val, int mod) {
exists(SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge |
edge.phiInput(phi, inp) and
ssaModulus(inp, edge, b, val, mod)
)
}
/**
* Holds if all inputs to `phi` numbered `1` to `rix` are equal to `b + val` modulo `mod`.
*/
pragma[nomagic]
private predicate phiModulusRankStep(
SemSsaPhiNode phi, Bounds::SemBound b, int val, int mod, int rix
) {
/*
* base case. If any phi input is equal to `b + val` modulo `mod`, that's a potential congruence
* class for the phi node.
*/
rix = 0 and
phiModulusInit(phi, b, val, mod)
or
exists(SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge, int v1, int m1 |
mod != 1 and
val = remainder(v1, mod)
|
/*
* Recursive case. If `inp` = `b + v2` mod `m2`, we combine that with the preceding potential
* congruence class `b + v1` mod `m1`. The result will be the congruence class of `v1` modulo
* the greatest common denominator of `m1`, `m2`, and `v1 - v2`.
*/
exists(int v2, int m2 |
rankedPhiInput(pragma[only_bind_out](phi), inp, edge, rix) and
phiModulusRankStep(phi, b, v1, m1, rix - 1) and
ssaModulus(inp, edge, b, v2, m2) and
mod = m1.gcd(m2).gcd(v1 - v2)
)
or
/*
* Recursive case. If `inp` = `phi` mod `m2`, we combine that with the preceding potential
* congruence class `b + v1` mod `m1`. The result will be a congruence class modulo the greatest
* common denominator of `m1` and `m2`.
*/
exists(int m2 |
rankedPhiInput(phi, inp, edge, rix) and
phiModulusRankStep(phi, b, v1, m1, rix - 1) and
phiSelfModulus(phi, inp, edge, m2) and
mod = m1.gcd(m2)
)
)
}
/**
* Holds if `phi` is equal to `b + val` modulo `mod`.
*/
private predicate phiModulus(SemSsaPhiNode phi, Bounds::SemBound b, int val, int mod) {
exists(int r |
maxPhiInputRank(phi, r) and
phiModulusRankStep(phi, b, val, mod, r)
)
}
/**
* Holds if `v` at `pos` is equal to `b + val` modulo `mod`.
*/
private predicate ssaModulus(
SemSsaVariable v, SemSsaReadPosition pos, Bounds::SemBound b, int val, int mod
) {
phiModulus(v, b, val, mod) and pos.hasReadOfVar(v)
or
b.(Bounds::SemSsaBound).getAVariable() = v and pos.hasReadOfVar(v) and val = 0 and mod = 0
or
exists(SemExpr e, int val0, int delta |
semExprModulus(e, b, val0, mod) and
valueFlowStepSsa(v, pos, e, delta) and
val = remainder(val0 + delta, mod)
)
or
moduloGuardedRead(v, pos, val, mod) and b instanceof Bounds::SemZeroBound
}
/**
* Holds if `e` is equal to `b + val` modulo `mod`.
*
* There are two cases for the modulus:
* - `mod = 0`: The equality `e = b + val` is an ordinary equality.
* - `mod > 1`: `val` lies within the range `[0 .. mod-1]`.
*/
cached
predicate semExprModulus(SemExpr e, Bounds::SemBound b, int val, int mod) {
not ignoreExprModulus(e) and
(
e = b.getExpr(D::fromInt(val)) and mod = 0
or
evenlyDivisibleExpr(e, mod) and
val = 0 and
b instanceof Bounds::SemZeroBound
or
exists(SemSsaVariable v, SemSsaReadPositionBlock bb |
ssaModulus(v, bb, b, val, mod) and
e = v.getAUse() and
bb.getAnExpr() = e
)
or
exists(SemExpr mid, int val0, int delta |
semExprModulus(mid, b, val0, mod) and
U::semValueFlowStep(e, mid, D::fromInt(delta)) and
val = remainder(val0 + delta, mod)
)
or
exists(SemConditionalExpr cond, int v1, int v2, int m1, int m2 |
cond = e and
condExprBranchModulus(cond, true, b, v1, m1) and
condExprBranchModulus(cond, false, b, v2, m2) and
mod = m1.gcd(m2).gcd(v1 - v2) and
mod != 1 and
val = remainder(v1, mod)
)
or
exists(Bounds::SemBound b1, Bounds::SemBound b2, int v1, int v2, int m1, int m2 |
addModulus(e, true, b1, v1, m1) and
addModulus(e, false, b2, v2, m2) and
mod = m1.gcd(m2) and
mod != 1 and
val = remainder(v1 + v2, mod)
|
b = b1 and b2 instanceof Bounds::SemZeroBound
or
b = b2 and b1 instanceof Bounds::SemZeroBound
)
or
exists(int v1, int v2, int m1, int m2 |
subModulus(e, true, b, v1, m1) and
subModulus(e, false, any(Bounds::SemZeroBound zb), v2, m2) and
mod = m1.gcd(m2) and
mod != 1 and
val = remainder(v1 - v2, mod)
)
)
}
private predicate condExprBranchModulus(
SemConditionalExpr cond, boolean branch, Bounds::SemBound b, int val, int mod
) {
semExprModulus(cond.getBranchExpr(branch), b, val, mod)
}
private predicate addModulus(SemExpr add, boolean isLeft, Bounds::SemBound b, int val, int mod) {
exists(SemExpr larg, SemExpr rarg | nonConstAddition(add, larg, rarg) |
semExprModulus(larg, b, val, mod) and isLeft = true
or
semExprModulus(rarg, b, val, mod) and isLeft = false
)
}
private predicate subModulus(SemExpr sub, boolean isLeft, Bounds::SemBound b, int val, int mod) {
exists(SemExpr larg, SemExpr rarg | nonConstSubtraction(sub, larg, rarg) |
semExprModulus(larg, b, val, mod) and isLeft = true
or
semExprModulus(rarg, b, val, mod) and isLeft = false
)
}
}

View File

@@ -1,8 +0,0 @@
/**
* C++-specific implementation of modulus analysis.
*/
module Private {
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
predicate ignoreExprModulus(SemExpr e) { none() }
}

View File

@@ -8,14 +8,6 @@ private import RangeAnalysisImpl
private import codeql.rangeanalysis.RangeAnalysis
module CppLangImplConstant implements LangSig<Sem, FloatDelta> {
/**
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreSsaReadCopy(SemExpr e) { none() }
/**
* Ignore the bound on this expression.
*
@@ -24,70 +16,13 @@ module CppLangImplConstant implements LangSig<Sem, FloatDelta> {
*/
predicate ignoreExprBound(SemExpr e) { none() }
/**
* Ignore any inferred zero lower bound on this expression.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreZeroLowerBound(SemExpr e) { none() }
/**
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreSsaReadArithmeticExpr(SemExpr e) { none() }
/**
* Holds if the specified variable should be excluded from the result of `ssaRead()`.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreSsaReadAssignment(SemSsaVariable v) { none() }
/**
* Adds additional results to `ssaRead()` that are specific to Java.
*
* This predicate handles propagation of offsets for post-increment and post-decrement expressions
* in exactly the same way as the old Java implementation. Once the new implementation matches the
* old one, we should remove this predicate and propagate deltas for all similar patterns, whether
* or not they come from a post-increment/decrement expression.
*/
SemExpr specificSsaRead(SemSsaVariable v, float delta) { none() }
/**
* Holds if `e >= bound` (if `upper = false`) or `e <= bound` (if `upper = true`).
*/
predicate hasConstantBound(SemExpr e, float bound, boolean upper) { none() }
/**
* Holds if `e >= bound + delta` (if `upper = false`) or `e <= bound + delta` (if `upper = true`).
* Holds if `e2 >= e1 + delta` (if `upper = false`) or `e2 <= e1 + delta` (if `upper = true`).
*/
predicate hasBound(SemExpr e, SemExpr bound, float delta, boolean upper) { none() }
/**
* Holds if the value of `dest` is known to be `src + delta`.
*/
predicate additionalValueFlowStep(SemExpr dest, SemExpr src, float delta) { none() }
/**
* Gets the type that range analysis should use to track the result of the specified expression,
* if a type other than the original type of the expression is to be used.
*
* This predicate is commonly used in languages that support immutable "boxed" types that are
* actually references but whose values can be tracked as the type contained in the box.
*/
SemType getAlternateType(SemExpr e) { none() }
/**
* Gets the type that range analysis should use to track the result of the specified source
* variable, if a type other than the original type of the expression is to be used.
*
* This predicate is commonly used in languages that support immutable "boxed" types that are
* actually references but whose values can be tracked as the type contained in the box.
*/
SemType getAlternateTypeForSsaVariable(SemSsaVariable var) { none() }
predicate additionalBoundFlowStep(SemExpr e2, SemExpr e1, float delta, boolean upper) { none() }
}

View File

@@ -1,7 +1,6 @@
private import RangeAnalysisConstantSpecific
private import RangeAnalysisRelativeSpecific
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
private import RangeUtils
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExpr
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticCFG
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticGuard
@@ -52,20 +51,34 @@ module Sem implements Semantic {
class NegateExpr = SemNegateExpr;
class AddOneExpr = SemAddOneExpr;
class PreIncExpr = SemAddOneExpr;
class SubOneExpr = SemSubOneExpr;
class PreDecExpr = SemSubOneExpr;
class PostIncExpr extends SemUnaryExpr {
PostIncExpr() { none() }
}
class PostDecExpr extends SemUnaryExpr {
PostDecExpr() { none() }
}
class CopyValueExpr extends SemUnaryExpr {
CopyValueExpr() { this instanceof SemCopyValueExpr or this instanceof SemStoreExpr }
}
class ConditionalExpr = SemConditionalExpr;
class BasicBlock = SemBasicBlock;
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
int getBlockId1(BasicBlock bb) { result = bb.getUniqueId() }
class Guard = SemGuard;
predicate implies_v2 = semImplies_v2/4;
predicate guardDirectlyControlsSsaRead = semGuardDirectlyControlsSsaRead/3;
class Type = SemType;
class IntegerType = SemIntegerType;
@@ -74,19 +87,17 @@ module Sem implements Semantic {
class AddressType = SemAddressType;
SemType getExprType(SemExpr e) { result = e.getSemType() }
SemType getSsaType(SemSsaVariable var) { result = var.getType() }
class SsaVariable = SemSsaVariable;
class SsaPhiNode = SemSsaPhiNode;
class SsaExplicitUpdate = SemSsaExplicitUpdate;
class SsaReadPosition = SemSsaReadPosition;
class SsaReadPositionPhiInputEdge = SemSsaReadPositionPhiInputEdge;
class SsaReadPositionBlock = SemSsaReadPositionBlock;
predicate backEdge = semBackEdge/3;
predicate additionalValueFlowStep(SemExpr dest, SemExpr src, int delta) { none() }
predicate conversionCannotOverflow(Type fromType, Type toType) {
SemanticType::conversionCannotOverflow(fromType, toType)
@@ -95,7 +106,7 @@ module Sem implements Semantic {
module SignAnalysis implements SignAnalysisSig<Sem> {
private import SignAnalysisCommon as SA
import SA::SignAnalysis<FloatDelta, Util>
import SA::SignAnalysis<FloatDelta>
}
module ConstantBounds implements BoundSig<SemLocation, Sem, FloatDelta> {
@@ -116,7 +127,7 @@ module ConstantBounds implements BoundSig<SemLocation, Sem, FloatDelta> {
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
SemSsaVariable getVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
}
}
@@ -134,7 +145,7 @@ module RelativeBounds implements BoundSig<SemLocation, Sem, FloatDelta> {
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
SemSsaVariable getVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
}
}
@@ -150,26 +161,24 @@ module AllBounds implements BoundSig<SemLocation, Sem, FloatDelta> {
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
SemSsaVariable getVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
}
}
private module ModulusAnalysisInstantiated implements ModulusAnalysisSig<Sem> {
class ModBound = AllBounds::SemBound;
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.ModulusAnalysis as MA
import MA::ModulusAnalysis<FloatDelta, AllBounds, Util>
private import codeql.rangeanalysis.ModulusAnalysis as MA
import MA::ModulusAnalysis<SemLocation, Sem, FloatDelta, AllBounds>
}
module Util = RangeUtil<FloatDelta, CppLangImplConstant>;
module ConstantStage =
RangeStage<SemLocation, Sem, FloatDelta, ConstantBounds, FloatOverflow, CppLangImplConstant,
SignAnalysis, ModulusAnalysisInstantiated, Util>;
SignAnalysis, ModulusAnalysisInstantiated>;
module RelativeStage =
RangeStage<SemLocation, Sem, FloatDelta, RelativeBounds, FloatOverflow, CppLangImplRelative,
SignAnalysis, ModulusAnalysisInstantiated, Util>;
SignAnalysis, ModulusAnalysisInstantiated>;
private newtype TSemReason =
TSemNoReason() or

View File

@@ -9,14 +9,6 @@ private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
private import codeql.rangeanalysis.RangeAnalysis
module CppLangImplRelative implements LangSig<Sem, FloatDelta> {
/**
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreSsaReadCopy(SemExpr e) { none() }
/**
* Ignore the bound on this expression.
*
@@ -56,70 +48,13 @@ module CppLangImplRelative implements LangSig<Sem, FloatDelta> {
t instanceof SemFloatingPointType and lb = -(1.0 / 0.0) and ub = 1.0 / 0.0
}
/**
* Ignore any inferred zero lower bound on this expression.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreZeroLowerBound(SemExpr e) { none() }
/**
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreSsaReadArithmeticExpr(SemExpr e) { none() }
/**
* Holds if the specified variable should be excluded from the result of `ssaRead()`.
*
* This predicate is to keep the results identical to the original Java implementation. It should be
* removed once we have the new implementation matching the old results exactly.
*/
predicate ignoreSsaReadAssignment(SemSsaVariable v) { none() }
/**
* Adds additional results to `ssaRead()` that are specific to Java.
*
* This predicate handles propagation of offsets for post-increment and post-decrement expressions
* in exactly the same way as the old Java implementation. Once the new implementation matches the
* old one, we should remove this predicate and propagate deltas for all similar patterns, whether
* or not they come from a post-increment/decrement expression.
*/
SemExpr specificSsaRead(SemSsaVariable v, float delta) { none() }
/**
* Holds if `e >= bound` (if `upper = false`) or `e <= bound` (if `upper = true`).
*/
predicate hasConstantBound(SemExpr e, float bound, boolean upper) { none() }
/**
* Holds if `e >= bound + delta` (if `upper = false`) or `e <= bound + delta` (if `upper = true`).
* Holds if `e2 >= e1 + delta` (if `upper = false`) or `e2 <= e1 + delta` (if `upper = true`).
*/
predicate hasBound(SemExpr e, SemExpr bound, float delta, boolean upper) { none() }
/**
* Holds if the value of `dest` is known to be `src + delta`.
*/
predicate additionalValueFlowStep(SemExpr dest, SemExpr src, float delta) { none() }
/**
* Gets the type that range analysis should use to track the result of the specified expression,
* if a type other than the original type of the expression is to be used.
*
* This predicate is commonly used in languages that support immutable "boxed" types that are
* actually references but whose values can be tracked as the type contained in the box.
*/
SemType getAlternateType(SemExpr e) { none() }
/**
* Gets the type that range analysis should use to track the result of the specified source
* variable, if a type other than the original type of the expression is to be used.
*
* This predicate is commonly used in languages that support immutable "boxed" types that are
* actually references but whose values can be tracked as the type contained in the box.
*/
SemType getAlternateTypeForSsaVariable(SemSsaVariable var) { none() }
predicate additionalBoundFlowStep(SemExpr e2, SemExpr e1, float delta, boolean upper) { none() }
}

View File

@@ -1,171 +0,0 @@
/**
* Provides utility predicates for range analysis.
*/
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
private import RangeAnalysisRelativeSpecific
private import codeql.rangeanalysis.RangeAnalysis
private import RangeAnalysisImpl
private import ConstantAnalysis
module RangeUtil<DeltaSig D, LangSig<Sem, D> Lang> implements UtilSig<Sem, D> {
/**
* Gets an expression that equals `v - d`.
*/
SemExpr semSsaRead(SemSsaVariable v, D::Delta delta) {
// There are various language-specific extension points that can be removed once we no longer
// expect to match the original Java implementation's results exactly.
result = v.getAUse() and delta = D::fromInt(0)
or
exists(D::Delta d1, SemConstantIntegerExpr c |
result.(SemAddExpr).hasOperands(semSsaRead(v, d1), c) and
delta = D::fromFloat(D::toFloat(d1) - c.getIntValue()) and
not Lang::ignoreSsaReadArithmeticExpr(result)
)
or
exists(SemSubExpr sub, D::Delta d1, SemConstantIntegerExpr c |
result = sub and
sub.getLeftOperand() = semSsaRead(v, d1) and
sub.getRightOperand() = c and
delta = D::fromFloat(D::toFloat(d1) + c.getIntValue()) and
not Lang::ignoreSsaReadArithmeticExpr(result)
)
or
result = v.(SemSsaExplicitUpdate).getSourceExpr() and
delta = D::fromFloat(0) and
not Lang::ignoreSsaReadAssignment(v)
or
result = Lang::specificSsaRead(v, delta)
or
result.(SemCopyValueExpr).getOperand() = semSsaRead(v, delta) and
not Lang::ignoreSsaReadCopy(result)
or
result.(SemStoreExpr).getOperand() = semSsaRead(v, delta)
}
/**
* Gets a condition that tests whether `v` equals `e + delta`.
*
* If the condition evaluates to `testIsTrue`:
* - `isEq = true` : `v == e + delta`
* - `isEq = false` : `v != e + delta`
*/
pragma[nomagic]
SemGuard semEqFlowCond(
SemSsaVariable v, SemExpr e, D::Delta delta, boolean isEq, boolean testIsTrue
) {
exists(boolean eqpolarity |
result.isEquality(semSsaRead(v, delta), e, eqpolarity) and
(testIsTrue = true or testIsTrue = false) and
eqpolarity.booleanXor(testIsTrue).booleanNot() = isEq
)
or
exists(boolean testIsTrue0 |
semImplies_v2(result, testIsTrue, semEqFlowCond(v, e, delta, isEq, testIsTrue0), testIsTrue0)
)
}
/**
* Holds if `v` is an `SsaExplicitUpdate` that equals `e + delta`.
*/
predicate semSsaUpdateStep(SemSsaExplicitUpdate v, SemExpr e, D::Delta delta) {
exists(SemExpr defExpr | defExpr = v.getSourceExpr() |
defExpr.(SemCopyValueExpr).getOperand() = e and delta = D::fromFloat(0)
or
defExpr.(SemStoreExpr).getOperand() = e and delta = D::fromFloat(0)
or
defExpr.(SemAddOneExpr).getOperand() = e and delta = D::fromFloat(1)
or
defExpr.(SemSubOneExpr).getOperand() = e and delta = D::fromFloat(-1)
or
e = defExpr and
not (
defExpr instanceof SemCopyValueExpr or
defExpr instanceof SemStoreExpr or
defExpr instanceof SemAddOneExpr or
defExpr instanceof SemSubOneExpr
) and
delta = D::fromFloat(0)
)
}
/**
* Holds if `e1 + delta` equals `e2`.
*/
predicate semValueFlowStep(SemExpr e2, SemExpr e1, D::Delta delta) {
e2.(SemCopyValueExpr).getOperand() = e1 and delta = D::fromFloat(0)
or
e2.(SemStoreExpr).getOperand() = e1 and delta = D::fromFloat(0)
or
e2.(SemAddOneExpr).getOperand() = e1 and delta = D::fromFloat(1)
or
e2.(SemSubOneExpr).getOperand() = e1 and delta = D::fromFloat(-1)
or
Lang::additionalValueFlowStep(e2, e1, delta)
or
exists(SemExpr x | e2.(SemAddExpr).hasOperands(e1, x) |
D::fromInt(x.(SemConstantIntegerExpr).getIntValue()) = delta
)
or
exists(SemExpr x, SemSubExpr sub |
e2 = sub and
sub.getLeftOperand() = e1 and
sub.getRightOperand() = x
|
D::fromInt(-x.(SemConstantIntegerExpr).getIntValue()) = delta
)
}
/**
* Gets the type used to track the specified expression's range information.
*
* Usually, this just `e.getSemType()`, but the language can override this to track immutable boxed
* primitive types as the underlying primitive type.
*/
SemType getTrackedType(SemExpr e) {
result = Lang::getAlternateType(e)
or
not exists(Lang::getAlternateType(e)) and result = e.getSemType()
}
/**
* Gets the type used to track the specified source variable's range information.
*
* Usually, this just `e.getType()`, but the language can override this to track immutable boxed
* primitive types as the underlying primitive type.
*/
SemType getTrackedTypeForSsaVariable(SemSsaVariable var) {
result = Lang::getAlternateTypeForSsaVariable(var)
or
not exists(Lang::getAlternateTypeForSsaVariable(var)) and result = var.getType()
}
import Ranking
}
import Ranking
module Ranking {
/**
* Holds if `rix` is the number of input edges to `phi`.
*/
predicate maxPhiInputRank(SemSsaPhiNode phi, int rix) {
rix = max(int r | rankedPhiInput(phi, _, _, r))
}
/**
* Holds if `inp` is an input to `phi` along `edge` and this input has index `r`
* in an arbitrary 1-based numbering of the input edges to `phi`.
*/
predicate rankedPhiInput(
SemSsaPhiNode phi, SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge, int r
) {
edge.phiInput(phi, inp) and
edge =
rank[r](SemSsaReadPositionPhiInputEdge e |
e.phiInput(phi, _)
|
e order by e.getOrigBlock().getUniqueId()
)
}
}

View File

@@ -11,10 +11,11 @@ private import RangeAnalysisImpl
private import SignAnalysisSpecific as Specific
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
private import ConstantAnalysis
private import RangeUtils
private import Sign
module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
module SignAnalysis<DeltaSig D> {
private import codeql.rangeanalysis.internal.RangeUtils::MakeUtils<Sem, D>
/**
* An SSA definition for which the analysis can compute the sign.
*
@@ -37,13 +38,13 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
/** An SSA definition whose sign is determined by the sign of that definitions source expression. */
private class ExplicitSignDef extends FlowSignDef instanceof SemSsaExplicitUpdate {
final override Sign getSign() { result = semExprSign(super.getSourceExpr()) }
final override Sign getSign() { result = semExprSign(super.getDefiningExpr()) }
}
/** An SSA Phi definition, whose sign is the union of the signs of its inputs. */
private class PhiSignDef extends FlowSignDef instanceof SemSsaPhiNode {
final override Sign getSign() {
exists(SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge |
exists(SemSsaVariable inp, SsaReadPositionPhiInputEdge edge |
edge.phiInput(this, inp) and
result = semSsaSign(inp, edge)
)
@@ -146,7 +147,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
not this instanceof ConstantSignExpr and
(
// Only track numeric types.
Utils::getTrackedType(this) instanceof SemNumericType
Sem::getExprType(this) instanceof SemNumericType
or
// Unless the language says to track this expression anyway.
Specific::trackUnknownNonNumericExpr(this)
@@ -168,11 +169,11 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
override Sign getSignRestriction() {
// Propagate via SSA
// Propagate the sign from the def of `v`, incorporating any inference from guards.
result = semSsaSign(v, any(SemSsaReadPositionBlock bb | bb.getAnExpr() = this))
result = semSsaSign(v, any(SsaReadPositionBlock bb | bb.getBlock().getAnExpr() = this))
or
// No block for this read. Just use the sign of the def.
// REVIEW: How can this happen?
not exists(SemSsaReadPositionBlock bb | bb.getAnExpr() = this) and
not exists(SsaReadPositionBlock bb | bb.getBlock().getAnExpr() = this) and
result = semSsaDefSign(v)
}
}
@@ -201,7 +202,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
/** An expression of an unsigned type. */
private class UnsignedExpr extends FlowSignExpr {
UnsignedExpr() { Utils::getTrackedType(this) instanceof SemUnsignedIntegerType }
UnsignedExpr() { Sem::getExprType(this) instanceof SemUnsignedIntegerType }
override Sign getSignRestriction() {
result = TPos() or
@@ -274,7 +275,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
override SemUnboxExpr cast;
UnboxSignExpr() {
exists(SemType fromType | fromType = Utils::getTrackedType(cast.getOperand()) |
exists(SemType fromType | fromType = Sem::getExprType(cast.getOperand()) |
// Only numeric source types are handled here.
fromType instanceof SemNumericType
)
@@ -288,21 +289,21 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
* to only include bounds for which we might determine a sign.
*/
private predicate lowerBound(
SemExpr lowerbound, SemSsaVariable v, SemSsaReadPosition pos, boolean isStrict
SemExpr lowerbound, SemSsaVariable v, SsaReadPosition pos, boolean isStrict
) {
exists(boolean testIsTrue, SemRelationalExpr comp |
pos.hasReadOfVar(v) and
semGuardControlsSsaRead(semGetComparisonGuard(comp), pos, testIsTrue) and
guardControlsSsaRead(semGetComparisonGuard(comp), pos, testIsTrue) and
not unknownSign(lowerbound)
|
testIsTrue = true and
comp.getLesserOperand() = lowerbound and
comp.getGreaterOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
comp.getGreaterOperand() = ssaRead(v, D::fromInt(0)) and
(if comp.isStrict() then isStrict = true else isStrict = false)
or
testIsTrue = false and
comp.getGreaterOperand() = lowerbound and
comp.getLesserOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
comp.getLesserOperand() = ssaRead(v, D::fromInt(0)) and
(if comp.isStrict() then isStrict = false else isStrict = true)
)
}
@@ -312,21 +313,21 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
* to only include bounds for which we might determine a sign.
*/
private predicate upperBound(
SemExpr upperbound, SemSsaVariable v, SemSsaReadPosition pos, boolean isStrict
SemExpr upperbound, SemSsaVariable v, SsaReadPosition pos, boolean isStrict
) {
exists(boolean testIsTrue, SemRelationalExpr comp |
pos.hasReadOfVar(v) and
semGuardControlsSsaRead(semGetComparisonGuard(comp), pos, testIsTrue) and
guardControlsSsaRead(semGetComparisonGuard(comp), pos, testIsTrue) and
not unknownSign(upperbound)
|
testIsTrue = true and
comp.getGreaterOperand() = upperbound and
comp.getLesserOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
comp.getLesserOperand() = ssaRead(v, D::fromInt(0)) and
(if comp.isStrict() then isStrict = true else isStrict = false)
or
testIsTrue = false and
comp.getLesserOperand() = upperbound and
comp.getGreaterOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
comp.getGreaterOperand() = ssaRead(v, D::fromInt(0)) and
(if comp.isStrict() then isStrict = false else isStrict = true)
)
}
@@ -338,11 +339,11 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
* - `isEq = true` : `v = eqbound`
* - `isEq = false` : `v != eqbound`
*/
private predicate eqBound(SemExpr eqbound, SemSsaVariable v, SemSsaReadPosition pos, boolean isEq) {
private predicate eqBound(SemExpr eqbound, SemSsaVariable v, SsaReadPosition pos, boolean isEq) {
exists(SemGuard guard, boolean testIsTrue, boolean polarity, SemExpr e |
pos.hasReadOfVar(pragma[only_bind_into](v)) and
semGuardControlsSsaRead(guard, pragma[only_bind_into](pos), testIsTrue) and
e = Utils::semSsaRead(pragma[only_bind_into](v), D::fromInt(0)) and
guardControlsSsaRead(guard, pragma[only_bind_into](pos), testIsTrue) and
e = ssaRead(pragma[only_bind_into](v), D::fromInt(0)) and
guard.isEquality(eqbound, e, polarity) and
isEq = polarity.booleanXor(testIsTrue).booleanNot() and
not unknownSign(eqbound)
@@ -353,7 +354,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
* Holds if `bound` is a bound for `v` at `pos` that needs to be positive in
* order for `v` to be positive.
*/
private predicate posBound(SemExpr bound, SemSsaVariable v, SemSsaReadPosition pos) {
private predicate posBound(SemExpr bound, SemSsaVariable v, SsaReadPosition pos) {
upperBound(bound, v, pos, _) or
eqBound(bound, v, pos, true)
}
@@ -362,7 +363,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
* Holds if `bound` is a bound for `v` at `pos` that needs to be negative in
* order for `v` to be negative.
*/
private predicate negBound(SemExpr bound, SemSsaVariable v, SemSsaReadPosition pos) {
private predicate negBound(SemExpr bound, SemSsaVariable v, SsaReadPosition pos) {
lowerBound(bound, v, pos, _) or
eqBound(bound, v, pos, true)
}
@@ -371,24 +372,24 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
* Holds if `bound` is a bound for `v` at `pos` that can restrict whether `v`
* can be zero.
*/
private predicate zeroBound(SemExpr bound, SemSsaVariable v, SemSsaReadPosition pos) {
private predicate zeroBound(SemExpr bound, SemSsaVariable v, SsaReadPosition pos) {
lowerBound(bound, v, pos, _) or
upperBound(bound, v, pos, _) or
eqBound(bound, v, pos, _)
}
/** Holds if `bound` allows `v` to be positive at `pos`. */
private predicate posBoundOk(SemExpr bound, SemSsaVariable v, SemSsaReadPosition pos) {
private predicate posBoundOk(SemExpr bound, SemSsaVariable v, SsaReadPosition pos) {
posBound(bound, v, pos) and TPos() = semExprSign(bound)
}
/** Holds if `bound` allows `v` to be negative at `pos`. */
private predicate negBoundOk(SemExpr bound, SemSsaVariable v, SemSsaReadPosition pos) {
private predicate negBoundOk(SemExpr bound, SemSsaVariable v, SsaReadPosition pos) {
negBound(bound, v, pos) and TNeg() = semExprSign(bound)
}
/** Holds if `bound` allows `v` to be zero at `pos`. */
private predicate zeroBoundOk(SemExpr bound, SemSsaVariable v, SemSsaReadPosition pos) {
private predicate zeroBoundOk(SemExpr bound, SemSsaVariable v, SsaReadPosition pos) {
lowerBound(bound, v, pos, _) and TNeg() = semExprSign(bound)
or
lowerBound(bound, v, pos, false) and TZero() = semExprSign(bound)
@@ -406,7 +407,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
* Holds if there is a bound that might restrict whether `v` has the sign `s`
* at `pos`.
*/
private predicate hasGuard(SemSsaVariable v, SemSsaReadPosition pos, Sign s) {
private predicate hasGuard(SemSsaVariable v, SsaReadPosition pos, Sign s) {
s = TPos() and posBound(_, v, pos)
or
s = TNeg() and negBound(_, v, pos)
@@ -419,7 +420,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
* might be ruled out by a guard.
*/
pragma[noinline]
private Sign guardedSsaSign(SemSsaVariable v, SemSsaReadPosition pos) {
private Sign guardedSsaSign(SemSsaVariable v, SsaReadPosition pos) {
result = semSsaDefSign(v) and
pos.hasReadOfVar(v) and
hasGuard(v, pos, result)
@@ -430,7 +431,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
* can rule it out.
*/
pragma[noinline]
private Sign unguardedSsaSign(SemSsaVariable v, SemSsaReadPosition pos) {
private Sign unguardedSsaSign(SemSsaVariable v, SsaReadPosition pos) {
result = semSsaDefSign(v) and
pos.hasReadOfVar(v) and
not hasGuard(v, pos, result)
@@ -441,7 +442,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
* ruled out the sign but does not.
* This does not check that the definition of `v` also allows the sign.
*/
private Sign guardedSsaSignOk(SemSsaVariable v, SemSsaReadPosition pos) {
private Sign guardedSsaSignOk(SemSsaVariable v, SsaReadPosition pos) {
result = TPos() and
forex(SemExpr bound | posBound(bound, v, pos) | posBoundOk(bound, v, pos))
or
@@ -453,7 +454,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
}
/** Gets a possible sign for `v` at `pos`. */
private Sign semSsaSign(SemSsaVariable v, SemSsaReadPosition pos) {
private Sign semSsaSign(SemSsaVariable v, SsaReadPosition pos) {
result = unguardedSsaSign(v, pos)
or
result = guardedSsaSign(v, pos) and
@@ -469,7 +470,7 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
Sign semExprSign(SemExpr e) {
exists(Sign s | s = e.(SignExpr).getSign() |
if
Utils::getTrackedType(e) instanceof SemUnsignedIntegerType and
Sem::getExprType(e) instanceof SemUnsignedIntegerType and
s = TNeg() and
not Specific::ignoreTypeRestrictions(e)
then result = TPos()

View File

@@ -23,9 +23,7 @@
* configuration (see `InvalidPointerToDerefConfig`).
*
* The dataflow traversal defines the set of sources as any dataflow node `n` such that there exists a pointer-arithmetic
* instruction `pai` found by `AllocationToInvalidPointer.qll` and a `n.asInstruction() >= pai + deltaDerefSourceAndPai`.
* Here, `deltaDerefSourceAndPai` is the constant difference between the source we track for finding a dereference and the
* pointer-arithmetic instruction.
* instruction `pai` found by `AllocationToInvalidPointer.qll` and a `n.asInstruction() = pai`.
*
* The set of sinks is defined as any dataflow node `n` such that `addr <= n.asInstruction() + deltaDerefSinkAndDerefAddress`
* for some address operand `addr` and constant difference `deltaDerefSinkAndDerefAddress`. Since an address operand is
@@ -37,9 +35,8 @@
* `deltaDerefSinkAndDerefAddress >= 0`. The load attached to `*p` is the "operation". To ensure that the path makes
* intuitive sense, we only pick operations that are control-flow reachable from the dereference sink.
*
* To compute how many elements the dereference is beyond the end position of the allocation, we sum the two deltas
* `deltaDerefSourceAndPai` and `deltaDerefSinkAndDerefAddress`. This is done in the `operationIsOffBy` predicate
* (which is the only predicate exposed by this file).
* We use the `deltaDerefSinkAndDerefAddress` to compute how many elements the dereference is beyond the end position of
* the allocation. This is done in the `operationIsOffBy` predicate (which is the only predicate exposed by this file).
*
* Handling false positives:
*
@@ -96,7 +93,7 @@ int invalidPointerToDereferenceFieldFlowBranchLimit() { result = 0 }
private module InvalidPointerToDerefBarrier {
private module BarrierConfig implements DataFlow::ConfigSig {
additional predicate isSource(DataFlow::Node source, PointerArithmeticInstruction pai) {
invalidPointerToDerefSource(_, pai, _, _) and
invalidPointerToDerefSource(_, pai, _) and
// source <= pai
bounded2(source.asInstruction(), pai, any(int d | d <= 0))
}
@@ -169,11 +166,11 @@ private module InvalidPointerToDerefBarrier {
*/
private module InvalidPointerToDerefConfig implements DataFlow::StateConfigSig {
class FlowState extends PointerArithmeticInstruction {
FlowState() { invalidPointerToDerefSource(_, this, _, _) }
FlowState() { invalidPointerToDerefSource(_, this, _) }
}
predicate isSource(DataFlow::Node source, FlowState pai) {
invalidPointerToDerefSource(_, pai, source, _)
invalidPointerToDerefSource(_, pai, source)
}
pragma[inline]
@@ -198,24 +195,17 @@ private import DataFlow::GlobalWithState<InvalidPointerToDerefConfig>
/**
* Holds if `allocSource` is dataflow node that represents an allocation that flows to the
* left-hand side of the pointer-arithmetic `pai`, and `derefSource <= pai + derefSourcePaiDelta`.
*
* For example, if `pai` is a pointer-arithmetic operation `p + size` in an expression such
* as `(p + size) + 1` and `derefSource` is the node representing `(p + size) + 1`. In this
* case `derefSourcePaiDelta` is 1.
* left-hand side of the pointer-arithmetic instruction represented by `derefSource`.
*/
private predicate invalidPointerToDerefSource(
DataFlow::Node allocSource, PointerArithmeticInstruction pai, DataFlow::Node derefSource,
int deltaDerefSourceAndPai
DataFlow::Node allocSource, PointerArithmeticInstruction pai, DataFlow::Node derefSource
) {
// Note that `deltaDerefSourceAndPai` is not necessarily equal to `rhsSizeDelta`:
// `rhsSizeDelta` is the constant offset added to the size of the allocation, and
// `deltaDerefSourceAndPai` is the constant difference between the pointer-arithmetic instruction
// and the instruction computing the address for which we will search for a dereference.
AllocToInvalidPointer::pointerAddInstructionHasBounds(allocSource, pai, _, _) and
// derefSource <= pai + deltaDerefSourceAndPai
bounded2(derefSource.asInstruction(), pai, deltaDerefSourceAndPai) and
deltaDerefSourceAndPai >= 0
derefSource.asInstruction() = pai
}
/**
@@ -258,11 +248,9 @@ private Instruction getASuccessor(Instruction instr) {
instr.getBlock().getASuccessor+() = result.getBlock()
}
private predicate paiForDereferenceSink(
PointerArithmeticInstruction pai, DataFlow::Node derefSink, int deltaDerefSourceAndPai
) {
private predicate paiForDereferenceSink(PointerArithmeticInstruction pai, DataFlow::Node derefSink) {
exists(DataFlow::Node derefSource |
invalidPointerToDerefSource(_, pai, derefSource, deltaDerefSourceAndPai) and
invalidPointerToDerefSource(_, pai, derefSource) and
flow(derefSource, derefSink)
)
}
@@ -274,10 +262,10 @@ private predicate paiForDereferenceSink(
*/
private predicate derefSinkToOperation(
DataFlow::Node derefSink, PointerArithmeticInstruction pai, DataFlow::Node operation,
string description, int deltaDerefSourceAndPai, int deltaDerefSinkAndDerefAddress
string description, int deltaDerefSinkAndDerefAddress
) {
exists(Instruction operationInstr, AddressOperand addr |
paiForDereferenceSink(pai, pragma[only_bind_into](derefSink), deltaDerefSourceAndPai) and
paiForDereferenceSink(pai, pragma[only_bind_into](derefSink)) and
isInvalidPointerDerefSink(derefSink, addr, operationInstr, description,
deltaDerefSinkAndDerefAddress) and
operationInstr = getASuccessor(derefSink.asInstruction()) and
@@ -298,11 +286,7 @@ predicate operationIsOffBy(
DataFlow::Node allocation, PointerArithmeticInstruction pai, DataFlow::Node derefSource,
DataFlow::Node derefSink, string description, DataFlow::Node operation, int delta
) {
exists(int deltaDerefSourceAndPai, int deltaDerefSinkAndDerefAddress |
invalidPointerToDerefSource(allocation, pai, derefSource, deltaDerefSourceAndPai) and
flow(derefSource, derefSink) and
derefSinkToOperation(derefSink, pai, operation, description, deltaDerefSourceAndPai,
deltaDerefSinkAndDerefAddress) and
delta = deltaDerefSourceAndPai + deltaDerefSinkAndDerefAddress
)
invalidPointerToDerefSource(allocation, pai, derefSource) and
flow(derefSource, derefSink) and
derefSinkToOperation(derefSink, pai, operation, description, delta)
}

View File

@@ -1334,11 +1334,16 @@ funbind(
| @assignxorexpr
| @assignlshiftexpr
| @assignrshiftexpr
| @assignpaddexpr
;
@assign_pointer_expr = @assignpaddexpr
| @assignpsubexpr
;
@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr
@assign_op_expr = @assign_arith_expr
| @assign_bitwise_expr
| @assign_pointer_expr
;
@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Removed @assignpaddexpr and @assignpsubexpr from @assign_bitwise_expr
compatibility: full

View File

@@ -1,3 +1,9 @@
## 0.8.3
### Minor Analysis Improvements
* The `cpp/uninitialized-local` query has been improved to produce fewer false positives.
## 0.8.2
No user-facing changes.

View File

@@ -27,16 +27,26 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
ReturnStackAllocatedMemoryConfig() { this = "ReturnStackAllocatedMemoryConfig" }
override predicate isSource(Instruction source) {
// Holds if `source` is a node that represents the use of a stack variable
exists(VariableAddressInstruction var, Function func |
var = source and
func = source.getEnclosingFunction() and
var.getAstVariable() instanceof StackVariable and
// Pointer-to-member types aren't properly handled in the dbscheme.
not var.getResultType() instanceof PointerToMemberType and
exists(Function func |
// Rule out FPs caused by extraction errors.
not any(ErrorExpr e).getEnclosingFunction() = func and
not intentionallyReturnsStackPointer(func)
not intentionallyReturnsStackPointer(func) and
func = source.getEnclosingFunction()
|
// `source` is an instruction that represents the use of a stack variable
exists(VariableAddressInstruction var |
var = source and
var.getAstVariable() instanceof StackVariable and
// Pointer-to-member types aren't properly handled in the dbscheme.
not var.getResultType() instanceof PointerToMemberType
)
or
// `source` is an instruction that represents the return value of a
// function that is known to return stack-allocated memory.
exists(Call call |
call.getTarget().hasGlobalName(["alloca", "strdupa", "strndupa", "_alloca", "_malloca"]) and
source.getUnconvertedResultExpression() = call
)
)
}
@@ -85,10 +95,10 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
}
from
MustFlowPathNode source, MustFlowPathNode sink, VariableAddressInstruction var,
MustFlowPathNode source, MustFlowPathNode sink, Instruction instr,
ReturnStackAllocatedMemoryConfig conf
where
conf.hasFlowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and
source.getInstruction() = var
source.getInstruction() = instr
select sink.getInstruction(), source, sink, "May return stack-allocated memory from $@.",
var.getAst(), var.getAst().toString()
instr.getAst(), instr.getAst().toString()

View File

@@ -13,7 +13,8 @@
*/
import cpp
import semmle.code.cpp.controlflow.StackVariableReachability
import semmle.code.cpp.ir.IR
import semmle.code.cpp.ir.dataflow.MustFlow
/**
* Auxiliary predicate: Types that don't require initialization
@@ -33,31 +34,6 @@ predicate allocatedType(Type t) {
allocatedType(t.getUnspecifiedType())
}
/**
* A declaration of a local variable that leaves the
* variable uninitialized.
*/
DeclStmt declWithNoInit(LocalVariable v) {
result.getADeclaration() = v and
not exists(v.getInitializer()) and
/* The type of the variable is not stack-allocated. */
exists(Type t | t = v.getType() | not allocatedType(t))
}
class UninitialisedLocalReachability extends StackVariableReachability {
UninitialisedLocalReachability() { this = "UninitialisedLocal" }
override predicate isSource(ControlFlowNode node, StackVariable v) { node = declWithNoInit(v) }
override predicate isSink(ControlFlowNode node, StackVariable v) { useOfVarActual(v, node) }
override predicate isBarrier(ControlFlowNode node, StackVariable v) {
// only report the _first_ possibly uninitialized use
useOfVarActual(v, node) or
definitionBarrier(v, node)
}
}
pragma[noinline]
predicate containsInlineAssembly(Function f) { exists(AsmStmt s | s.getEnclosingFunction() = f) }
@@ -82,8 +58,33 @@ VariableAccess commonException() {
containsInlineAssembly(result.getEnclosingFunction())
}
from UninitialisedLocalReachability r, LocalVariable v, VariableAccess va
predicate isSinkImpl(Instruction sink, VariableAccess va) {
exists(LoadInstruction load |
va = load.getUnconvertedResultExpression() and
not va = commonException() and
sink = load.getSourceValue()
)
}
class MustFlow extends MustFlowConfiguration {
MustFlow() { this = "MustFlow" }
override predicate isSource(Instruction source) {
source instanceof UninitializedInstruction and
exists(Type t | t = source.getResultType() | not allocatedType(t))
}
override predicate isSink(Operand sink) { isSinkImpl(sink.getDef(), _) }
override predicate allowInterproceduralFlow() { none() }
override predicate isBarrier(Instruction instr) { instr instanceof ChiInstruction }
}
from
VariableAccess va, LocalVariable v, MustFlow conf, MustFlowPathNode source, MustFlowPathNode sink
where
r.reaches(_, v, va) and
not va = commonException()
conf.hasFlowPath(source, sink) and
isSinkImpl(sink.getInstruction(), va) and
v = va.getTarget()
select va, "The variable $@ may not be initialized at this access.", v, v.getName()

View File

@@ -14,25 +14,47 @@
import cpp
import semmle.code.cpp.security.Security
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
import TaintedWithPath
import semmle.code.cpp.security.FlowSources
import semmle.code.cpp.ir.dataflow.TaintTracking
import semmle.code.cpp.ir.IR
import Flow::PathGraph
predicate isProcessOperationExplanation(Expr arg, string processOperation) {
predicate isProcessOperationExplanation(DataFlow::Node arg, string processOperation) {
exists(int processOperationArg, FunctionCall call |
isProcessOperationArgument(processOperation, processOperationArg) and
call.getTarget().getName() = processOperation and
call.getArgument(processOperationArg) = arg
call.getArgument(processOperationArg) = [arg.asExpr(), arg.asIndirectExpr()]
)
}
class Configuration extends TaintTrackingConfiguration {
override predicate isSink(Element arg) { isProcessOperationExplanation(arg, _) }
predicate isSource(FlowSource source, string sourceType) {
not source instanceof DataFlow::ExprNode and
sourceType = source.getSourceType()
}
from string processOperation, Expr arg, Expr source, PathNode sourceNode, PathNode sinkNode
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { isSource(node, _) }
predicate isSink(DataFlow::Node node) { isProcessOperationExplanation(node, _) }
predicate isBarrier(DataFlow::Node node) {
isSink(node) and node.asExpr().getUnspecifiedType() instanceof ArithmeticType
or
node.asInstruction().(StoreInstruction).getResultType() instanceof ArithmeticType
}
}
module Flow = TaintTracking::Global<Config>;
from
string processOperation, string sourceType, DataFlow::Node source, DataFlow::Node sink,
Flow::PathNode sourceNode, Flow::PathNode sinkNode
where
isProcessOperationExplanation(arg, processOperation) and
taintedWithPath(source, arg, sourceNode, sinkNode)
select arg, sourceNode, sinkNode,
source = sourceNode.getNode() and
sink = sinkNode.getNode() and
isSource(source, sourceType) and
isProcessOperationExplanation(sink, processOperation) and
Flow::flowPath(sourceNode, sinkNode)
select sink, sourceNode, sinkNode,
"The value of this argument may come from $@ and is being passed to " + processOperation + ".",
source, source.toString()
source, sourceType

View File

@@ -15,9 +15,10 @@
*/
import semmle.code.cpp.security.BufferWrite
import semmle.code.cpp.security.Security
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
import TaintedWithPath
import semmle.code.cpp.security.FlowSources as FS
import semmle.code.cpp.dataflow.new.TaintTracking
import semmle.code.cpp.controlflow.IRGuards
import Flow::PathGraph
/*
* --- Summary of CWE-120 alerts ---
@@ -47,38 +48,54 @@ predicate isUnboundedWrite(BufferWrite bw) {
not exists(bw.getMaxData(_)) // and we can't deduce an upper bound to the amount copied
}
/*
* predicate isMaybeUnboundedWrite(BufferWrite bw)
* {
* not bw.hasExplicitLimit() // has no explicit size limit
* and exists(bw.getMaxData()) // and we can deduce an upper bound to the amount copied
* and (not exists(getBufferSize(bw.getDest(), _))) // but we can't work out the size of the destination to be sure
* }
*/
/**
* Holds if `e` is a source buffer going into an unbounded write `bw` or a
* qualifier of (a qualifier of ...) such a source.
*/
predicate unboundedWriteSource(Expr e, BufferWrite bw) {
isUnboundedWrite(bw) and e = bw.getASource()
predicate unboundedWriteSource(Expr e, BufferWrite bw, boolean qualifier) {
isUnboundedWrite(bw) and e = bw.getASource() and qualifier = false
or
exists(FieldAccess fa | unboundedWriteSource(fa, bw) and e = fa.getQualifier())
exists(FieldAccess fa | unboundedWriteSource(fa, bw, _) and e = fa.getQualifier()) and
qualifier = true
}
/*
* --- user input reach ---
*/
predicate isSource(FS::FlowSource source, string sourceType) { source.getSourceType() = sourceType }
class Configuration extends TaintTrackingConfiguration {
override predicate isSink(Element tainted) { unboundedWriteSource(tainted, _) }
override predicate taintThroughGlobals() { any() }
predicate isSink(DataFlow::Node sink, BufferWrite bw, boolean qualifier) {
unboundedWriteSource(sink.asIndirectExpr(), bw, qualifier)
or
// `gets` and `scanf` reads from stdin so there's no real input.
// The `BufferWrite` library models this as the call itself being
// the source. In this case we mark the output argument as being
// the sink so that we report a path where source = sink (because
// the same output argument is also included in `isSource`).
bw.getASource() = bw and
unboundedWriteSource(sink.asDefiningArgument(), bw, qualifier)
}
/*
* --- put it together ---
*/
predicate lessThanOrEqual(IRGuardCondition g, Expr e, boolean branch) {
exists(Operand left |
g.comparesLt(left, _, _, true, branch) or
g.comparesEq(left, _, _, true, branch)
|
left.getDef().getUnconvertedResultExpression() = e
)
}
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { isSource(source, _) }
predicate isSink(DataFlow::Node sink) { isSink(sink, _, _) }
predicate isBarrierOut(DataFlow::Node node) { isSink(node, _, false) }
predicate isBarrier(DataFlow::Node node) {
// Block flow if the node is guarded by any <, <= or = operations.
node = DataFlow::BarrierGuard<lessThanOrEqual/3>::getABarrierNode()
}
}
module Flow = TaintTracking::Global<Config>;
/*
* An unbounded write is, for example `strcpy(..., tainted)`. We're looking
@@ -87,17 +104,20 @@ class Configuration extends TaintTrackingConfiguration {
*
* In the case of `gets` and `scanf`, where the source buffer is implicit, the
* `BufferWrite` library reports the source buffer to be the same as the
* destination buffer. Since those destination-buffer arguments are also
* modeled in the taint-tracking library as being _sources_ of taint, they are
* in practice reported as being tainted because the `security.TaintTracking`
* library does not distinguish between taint going into an argument and out of
* an argument. Thus, we get the desired alerts.
* destination buffer. So to report an alert on a pattern like:
* ```
* char s[32];
* gets(s);
* ```
* we define the sink as the node corresponding to the output argument of `gets`.
* This gives us a path where the source is equal to the sink.
*/
from BufferWrite bw, Expr inputSource, Expr tainted, PathNode sourceNode, PathNode sinkNode
from BufferWrite bw, Flow::PathNode source, Flow::PathNode sink, string sourceType
where
taintedWithPath(inputSource, tainted, sourceNode, sinkNode) and
unboundedWriteSource(tainted, bw)
select bw, sourceNode, sinkNode,
"This '" + bw.getBWDesc() + "' with input from $@ may overflow the destination.", inputSource,
inputSource.toString()
Flow::flowPath(source, sink) and
isSource(source.getNode(), sourceType) and
isSink(sink.getNode(), bw, _)
select bw, source, sink,
"This '" + bw.getBWDesc() + "' with input from $@ may overflow the destination.",
source.getNode(), sourceType

View File

@@ -14,10 +14,13 @@
import cpp
import semmle.code.cpp.security.Overflow
import semmle.code.cpp.security.Security
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
import TaintedWithPath
import semmle.code.cpp.dataflow.new.TaintTracking
import semmle.code.cpp.dataflow.new.DataFlow
import semmle.code.cpp.ir.IR
import semmle.code.cpp.controlflow.IRGuards as IRGuards
import semmle.code.cpp.security.FlowSources as FS
import Bounded
import Flow::PathGraph
bindingset[op]
predicate missingGuard(Operation op, Expr e, string effect) {
@@ -28,28 +31,90 @@ predicate missingGuard(Operation op, Expr e, string effect) {
not e instanceof VariableAccess and effect = "overflow"
}
class Configuration extends TaintTrackingConfiguration {
override predicate isSink(Element e) {
exists(Operation op |
missingGuard(op, e, _) and
op.getAnOperand() = e
|
op instanceof UnaryArithmeticOperation or
op instanceof BinaryArithmeticOperation or
op instanceof AssignArithmeticOperation
)
}
predicate isSource(FS::FlowSource source, string sourceType) { sourceType = source.getSourceType() }
override predicate isBarrier(Expr e) {
super.isBarrier(e) or bounded(e) or e.getUnspecifiedType().(IntegralType).getSize() <= 1
predicate isSink(DataFlow::Node sink, Operation op, Expr e) {
e = sink.asExpr() and
missingGuard(op, e, _) and
op.getAnOperand() = e and
(
op instanceof UnaryArithmeticOperation or
op instanceof BinaryArithmeticOperation or
op instanceof AssignArithmeticOperation
)
}
predicate hasUpperBoundsCheck(Variable var) {
exists(RelationalOperation oper, VariableAccess access |
oper.getAnOperand() = access and
access.getTarget() = var and
// Comparing to 0 is not an upper bound check
not oper.getAnOperand().getValue() = "0"
)
}
predicate constantInstruction(Instruction instr) {
instr instanceof ConstantInstruction or
constantInstruction(instr.(UnaryInstruction).getUnary())
}
predicate readsVariable(LoadInstruction load, Variable var) {
load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var
}
predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Variable checkedVar) {
exists(Instruction instr | instr = node.asInstruction() |
readsVariable(instr, checkedVar) and
any(IRGuards::IRGuardCondition guard).ensuresEq(access, _, _, instr.getBlock(), true)
)
}
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { isSource(source, _) }
predicate isSink(DataFlow::Node sink) { isSink(sink, _, _) }
predicate isBarrier(DataFlow::Node node) {
exists(StoreInstruction store | store = node.asInstruction() |
// Block flow to "likely small expressions"
bounded(store.getSourceValue().getUnconvertedResultExpression())
or
// Block flow to "small types"
store.getResultType().getUnspecifiedType().(IntegralType).getSize() <= 1
)
or
// Block flow if there's an upper bound check of the variable anywhere in the program
exists(Variable checkedVar, Instruction instr | instr = node.asInstruction() |
readsVariable(instr, checkedVar) and
hasUpperBoundsCheck(checkedVar)
)
or
// Block flow if the node is guarded by an equality check
exists(Variable checkedVar, Operand access |
nodeIsBarrierEqualityCandidate(node, access, checkedVar) and
readsVariable(access.getDef(), checkedVar)
)
or
// Block flow to any binary instruction whose operands are both non-constants.
exists(BinaryInstruction iTo |
iTo = node.asInstruction() and
not constantInstruction(iTo.getLeft()) and
not constantInstruction(iTo.getRight()) and
// propagate taint from either the pointer or the offset, regardless of constantness
not iTo instanceof PointerArithmeticInstruction
)
}
}
from Expr origin, Expr e, string effect, PathNode sourceNode, PathNode sinkNode, Operation op
module Flow = TaintTracking::Global<Config>;
from
Expr e, string effect, Flow::PathNode source, Flow::PathNode sink, Operation op, string sourceType
where
taintedWithPath(origin, e, sourceNode, sinkNode) and
op.getAnOperand() = e and
Flow::flowPath(source, sink) and
isSource(source.getNode(), sourceType) and
isSink(sink.getNode(), op, e) and
missingGuard(op, e, effect)
select e, sourceNode, sinkNode,
select e, source, sink,
"$@ flows to an operand of an arithmetic expression, potentially causing an " + effect + ".",
origin, "User-provided value"
source, sourceType

View File

@@ -8,7 +8,6 @@
* @id cpp/invalid-pointer-deref
* @tags reliability
* security
* experimental
* external/cwe/cwe-119
* external/cwe/cwe-125
* external/cwe/cwe-193

View File

@@ -15,6 +15,7 @@
import cpp
import semmle.code.cpp.ir.dataflow.TaintTracking
import semmle.code.cpp.models.interfaces.FlowSource
import semmle.code.cpp.models.implementations.Memset
import ExposedSystemData::PathGraph
import SystemData
@@ -28,6 +29,10 @@ module ExposedSystemDataConfig implements DataFlow::ConfigSig {
fc.getArgument(arg).getAChild*() = sink.asIndirectExpr()
)
}
predicate isBarrier(DataFlow::Node node) {
node.asIndirectArgument() = any(MemsetFunction func).getACallToThisFunction().getAnArgument()
}
}
module ExposedSystemData = TaintTracking::Global<ExposedSystemDataConfig>;

View File

@@ -28,6 +28,7 @@ import cpp
import semmle.code.cpp.ir.dataflow.TaintTracking
import semmle.code.cpp.models.interfaces.FlowSource
import semmle.code.cpp.security.OutputWrite
import semmle.code.cpp.models.implementations.Memset
import PotentiallyExposedSystemData::PathGraph
import SystemData
@@ -49,6 +50,10 @@ module PotentiallyExposedSystemDataConfig implements DataFlow::ConfigSig {
else child = sink.asExpr()
)
}
predicate isBarrier(DataFlow::Node node) {
node.asIndirectArgument() = any(MemsetFunction func).getACallToThisFunction().getAnArgument()
}
}
module PotentiallyExposedSystemData = TaintTracking::Global<PotentiallyExposedSystemDataConfig>;

View File

@@ -4,6 +4,7 @@
* @description The total number of lines of C/C++ code across all files, including system headers, libraries, and auto-generated files. This is a useful metric of the size of a database. For all files that were seen during the build, this query counts the lines of code, excluding whitespace or comments.
* @kind metric
* @tags summary
* telemetry
*/
import cpp

View File

@@ -0,0 +1,5 @@
## 0.8.3
### Minor Analysis Improvements
* The `cpp/uninitialized-local` query has been improved to produce fewer false positives.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.8.2
lastReleaseVersion: 0.8.3

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 0.8.2
version: 0.8.3
groups:
- cpp
- queries

View File

@@ -29,7 +29,6 @@ edges
| test.cpp:69:10:69:10 | arr indirection [post update] [p] | test.cpp:70:5:70:7 | arr indirection [p] |
| test.cpp:69:14:69:19 | call to malloc | test.cpp:69:5:69:25 | ... = ... |
| test.cpp:70:5:70:7 | arr indirection [p] | test.cpp:67:10:67:19 | mk_array_p indirection [p] |
| test.cpp:70:5:70:7 | arr indirection [p] | test.cpp:70:5:70:7 | arr indirection [p] |
| test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | test.cpp:79:9:79:11 | arr indirection [p] |
| test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | test.cpp:83:9:83:11 | arr indirection [p] |
| test.cpp:79:9:79:11 | arr indirection [p] | test.cpp:79:14:79:14 | p |

View File

@@ -23,6 +23,7 @@ argHasPostUpdate
| lambdas.cpp:38:2:38:2 | d | ArgumentNode is missing PostUpdateNode. |
| lambdas.cpp:45:2:45:2 | e | ArgumentNode is missing PostUpdateNode. |
| test.cpp:67:29:67:35 | source1 | ArgumentNode is missing PostUpdateNode. |
| test.cpp:813:19:813:35 | * ... | ArgumentNode is missing PostUpdateNode. |
postWithInFlow
| BarrierGuard.cpp:49:6:49:6 | x [post update] | PostUpdateNode should not be the target of local flow. |
| BarrierGuard.cpp:60:7:60:7 | x [post update] | PostUpdateNode should not be the target of local flow. |
@@ -41,6 +42,9 @@ postWithInFlow
| example.c:26:9:26:9 | x [post update] | PostUpdateNode should not be the target of local flow. |
| example.c:26:19:26:24 | coords [inner post update] | PostUpdateNode should not be the target of local flow. |
| example.c:28:23:28:25 | pos [inner post update] | PostUpdateNode should not be the target of local flow. |
| flowOut.cpp:5:5:5:12 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| flowOut.cpp:5:6:5:12 | toTaint [inner post update] | PostUpdateNode should not be the target of local flow. |
| flowOut.cpp:18:17:18:17 | x [inner post update] | PostUpdateNode should not be the target of local flow. |
| globals.cpp:13:5:13:19 | flowTestGlobal1 [post update] | PostUpdateNode should not be the target of local flow. |
| globals.cpp:23:5:23:19 | flowTestGlobal2 [post update] | PostUpdateNode should not be the target of local flow. |
| lambdas.cpp:23:3:23:14 | v [post update] | PostUpdateNode should not be the target of local flow. |
@@ -133,6 +137,9 @@ postWithInFlow
| test.cpp:728:3:728:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:728:4:728:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:734:41:734:41 | x [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:808:5:808:21 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:808:6:808:21 | global_indirect1 [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:832:5:832:17 | global_direct [post update] | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge
uniqueParameterNodeAtPosition
uniqueParameterNodePosition

View File

@@ -0,0 +1,20 @@
int source();
void sink(int);
void source_ref(int *toTaint) { // $ ir-def=*toTaint ast-def=toTaint
*toTaint = source();
}
void modify_copy(int* ptr) { // $ ast-def=ptr
int deref = *ptr;
int* other = &deref;
source_ref(other);
}
void test_output() {
int x = 0;
modify_copy(&x);
sink(x); // $ SPURIOUS: ir
}

View File

@@ -796,4 +796,44 @@ void test() {
MyStruct a;
intPointerSource(a.content, a.content);
indirect_sink(a.content); // $ ast ir
}
namespace MoreGlobalTests {
int **global_indirect1;
int **global_indirect2;
int **global_direct;
void set_indirect1()
{
*global_indirect1 = indirect_source();
}
void read_indirect1() {
sink(global_indirect1); // clean
indirect_sink(*global_indirect1); // $ ir MISSING: ast
}
void set_indirect2()
{
**global_indirect2 = source();
}
void read_indirect2() {
sink(global_indirect2); // clean
sink(**global_indirect2); // $ ir MISSING: ast
}
// overload source with a boolean parameter so
// that we can define a variant that return an int**.
int** source(bool);
void set_direct()
{
global_direct = source(true);
}
void read_direct() {
sink(global_direct); // $ ir MISSING: ast
indirect_sink(global_direct); // clean
}
}

View File

@@ -83,7 +83,6 @@ edges
| A.cpp:152:10:152:10 | d indirection [b] | A.cpp:152:10:152:13 | b |
| A.cpp:153:10:153:10 | d indirection [b indirection, c] | A.cpp:153:13:153:13 | b indirection [c] |
| A.cpp:153:13:153:13 | b indirection [c] | A.cpp:153:10:153:16 | c |
| A.cpp:153:13:153:13 | b indirection [c] | A.cpp:153:13:153:13 | b indirection [c] |
| A.cpp:154:10:154:10 | b indirection [c] | A.cpp:154:10:154:13 | c |
| A.cpp:159:12:159:18 | new | A.cpp:160:29:160:29 | b |
| A.cpp:160:18:160:60 | call to MyList [head] | A.cpp:161:38:161:39 | l1 indirection [head] |
@@ -97,10 +96,8 @@ edges
| A.cpp:162:38:162:39 | l2 indirection [next indirection, head] | A.cpp:162:18:162:40 | call to MyList [next indirection, next indirection, head] |
| A.cpp:162:38:162:39 | l2 indirection [next indirection, head] | A.cpp:181:32:181:35 | next indirection [next indirection, head] |
| A.cpp:165:10:165:11 | l3 indirection [next indirection, next indirection, head] | A.cpp:165:14:165:17 | next indirection [next indirection, head] |
| A.cpp:165:14:165:17 | next indirection [next indirection, head] | A.cpp:165:14:165:17 | next indirection [next indirection, head] |
| A.cpp:165:14:165:17 | next indirection [next indirection, head] | A.cpp:165:20:165:23 | next indirection [head] |
| A.cpp:165:20:165:23 | next indirection [head] | A.cpp:165:10:165:29 | head |
| A.cpp:165:20:165:23 | next indirection [head] | A.cpp:165:20:165:23 | next indirection [head] |
| A.cpp:167:44:167:44 | l indirection [next indirection, head] | A.cpp:167:47:167:50 | next indirection [head] |
| A.cpp:167:44:167:44 | l indirection [next indirection, next indirection, head] | A.cpp:167:47:167:50 | next indirection [next indirection, head] |
| A.cpp:167:47:167:50 | next indirection [head] | A.cpp:169:12:169:12 | l indirection [head] |
@@ -121,7 +118,6 @@ edges
| B.cpp:8:25:8:26 | b1 indirection [elem1] | B.cpp:44:16:44:17 | b1 indirection [elem1] |
| B.cpp:9:10:9:11 | b2 indirection [box1 indirection, elem1] | B.cpp:9:14:9:17 | box1 indirection [elem1] |
| B.cpp:9:14:9:17 | box1 indirection [elem1] | B.cpp:9:10:9:24 | elem1 |
| B.cpp:9:14:9:17 | box1 indirection [elem1] | B.cpp:9:14:9:17 | box1 indirection [elem1] |
| B.cpp:15:15:15:27 | new | B.cpp:16:37:16:37 | e |
| B.cpp:16:16:16:38 | call to Box1 [elem2] | B.cpp:17:25:17:26 | b1 indirection [elem2] |
| B.cpp:16:37:16:37 | e | B.cpp:16:16:16:38 | call to Box1 [elem2] |
@@ -131,7 +127,6 @@ edges
| B.cpp:17:25:17:26 | b1 indirection [elem2] | B.cpp:44:16:44:17 | b1 indirection [elem2] |
| B.cpp:19:10:19:11 | b2 indirection [box1 indirection, elem2] | B.cpp:19:14:19:17 | box1 indirection [elem2] |
| B.cpp:19:14:19:17 | box1 indirection [elem2] | B.cpp:19:10:19:24 | elem2 |
| B.cpp:19:14:19:17 | box1 indirection [elem2] | B.cpp:19:14:19:17 | box1 indirection [elem2] |
| B.cpp:33:16:33:17 | e1 | B.cpp:35:7:35:22 | ... = ... |
| B.cpp:33:26:33:27 | e2 | B.cpp:36:7:36:22 | ... = ... |
| B.cpp:35:7:35:22 | ... = ... | B.cpp:35:13:35:17 | this indirection [post update] [elem1] |
@@ -196,17 +191,12 @@ edges
| D.cpp:58:20:58:23 | box indirection [post update] [elem] | D.cpp:58:15:58:17 | boxfield indirection [post update] [box indirection, elem] |
| D.cpp:59:5:59:7 | this indirection [boxfield indirection, box indirection, elem] | D.cpp:63:8:63:10 | this indirection [boxfield indirection, box indirection, elem] |
| D.cpp:63:8:63:10 | this indirection [boxfield indirection, box indirection, elem] | D.cpp:64:10:64:17 | this indirection [boxfield indirection, box indirection, elem] |
| D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] |
| D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | D.cpp:64:20:64:22 | box indirection [elem] |
| D.cpp:64:10:64:17 | this indirection [boxfield indirection, box indirection, elem] | D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] |
| D.cpp:64:20:64:22 | box indirection [elem] | D.cpp:64:10:64:28 | elem |
| D.cpp:64:20:64:22 | box indirection [elem] | D.cpp:64:20:64:22 | box indirection [elem] |
| E.cpp:19:27:19:27 | p indirection [data, buffer indirection] | E.cpp:21:10:21:10 | p indirection [data, buffer indirection] |
| E.cpp:21:10:21:10 | p indirection [data, buffer indirection] | E.cpp:21:13:21:16 | data indirection [buffer indirection] |
| E.cpp:21:13:21:16 | data indirection [buffer indirection] | E.cpp:21:18:21:23 | buffer indirection |
| E.cpp:21:13:21:16 | data indirection [buffer indirection] | E.cpp:21:18:21:23 | buffer indirection |
| E.cpp:21:18:21:23 | buffer indirection | E.cpp:21:18:21:23 | buffer indirection |
| E.cpp:21:18:21:23 | buffer indirection | E.cpp:21:18:21:23 | buffer indirection |
| E.cpp:28:21:28:23 | argument_source output argument | E.cpp:31:10:31:12 | raw indirection |
| E.cpp:29:21:29:29 | argument_source output argument | E.cpp:29:24:29:29 | b indirection [post update] [buffer indirection] |
| E.cpp:29:24:29:29 | b indirection [post update] [buffer indirection] | E.cpp:32:10:32:10 | b indirection [buffer indirection] |
@@ -214,9 +204,6 @@ edges
| E.cpp:30:23:30:26 | p indirection [post update] [data, buffer indirection] | E.cpp:33:18:33:19 | & ... indirection [data, buffer indirection] |
| E.cpp:30:28:30:33 | data indirection [post update] [buffer indirection] | E.cpp:30:23:30:26 | p indirection [post update] [data, buffer indirection] |
| E.cpp:32:10:32:10 | b indirection [buffer indirection] | E.cpp:32:13:32:18 | buffer indirection |
| E.cpp:32:10:32:10 | b indirection [buffer indirection] | E.cpp:32:13:32:18 | buffer indirection |
| E.cpp:32:13:32:18 | buffer indirection | E.cpp:32:13:32:18 | buffer indirection |
| E.cpp:32:13:32:18 | buffer indirection | E.cpp:32:13:32:18 | buffer indirection |
| E.cpp:33:18:33:19 | & ... indirection [data, buffer indirection] | E.cpp:19:27:19:27 | p indirection [data, buffer indirection] |
| aliasing.cpp:9:3:9:22 | ... = ... | aliasing.cpp:9:6:9:7 | s indirection [post update] [m1] |
| aliasing.cpp:9:6:9:7 | s indirection [post update] [m1] | aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] |
@@ -311,11 +298,9 @@ edges
| arrays.cpp:43:8:43:8 | o indirection [indirect indirection, arr, data] | arrays.cpp:43:10:43:17 | indirect indirection [arr, data] |
| arrays.cpp:43:8:43:25 | access to array indirection [data] | arrays.cpp:43:27:43:30 | data |
| arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | arrays.cpp:43:8:43:25 | access to array indirection [data] |
| arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | arrays.cpp:43:10:43:17 | indirect indirection [arr, data] |
| arrays.cpp:44:8:44:8 | o indirection [indirect indirection, arr, data] | arrays.cpp:44:10:44:17 | indirect indirection [arr, data] |
| arrays.cpp:44:8:44:25 | access to array indirection [data] | arrays.cpp:44:27:44:30 | data |
| arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | arrays.cpp:44:8:44:25 | access to array indirection [data] |
| arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | arrays.cpp:44:10:44:17 | indirect indirection [arr, data] |
| arrays.cpp:48:3:48:40 | ... = ... | arrays.cpp:48:22:48:25 | access to array indirection [post update] [data] |
| arrays.cpp:48:5:48:12 | o indirection [post update] [indirect indirection, ptr indirection, data] | arrays.cpp:49:8:49:8 | o indirection [indirect indirection, ptr indirection, data] |
| arrays.cpp:48:5:48:12 | o indirection [post update] [indirect indirection, ptr indirection, data] | arrays.cpp:50:8:50:8 | o indirection [indirect indirection, ptr indirection, data] |
@@ -325,13 +310,11 @@ edges
| arrays.cpp:49:8:49:8 | o indirection [indirect indirection, ptr indirection, data] | arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] |
| arrays.cpp:49:8:49:25 | access to array indirection [data] | arrays.cpp:49:27:49:30 | data |
| arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | arrays.cpp:49:8:49:25 | access to array indirection [data] |
| arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] |
| arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | arrays.cpp:49:20:49:22 | ptr indirection [data] |
| arrays.cpp:49:20:49:22 | ptr indirection [data] | arrays.cpp:49:8:49:25 | access to array indirection [data] |
| arrays.cpp:50:8:50:8 | o indirection [indirect indirection, ptr indirection, data] | arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] |
| arrays.cpp:50:8:50:25 | access to array indirection [data] | arrays.cpp:50:27:50:30 | data |
| arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | arrays.cpp:50:8:50:25 | access to array indirection [data] |
| arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] |
| arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | arrays.cpp:50:20:50:22 | ptr indirection [data] |
| arrays.cpp:50:20:50:22 | ptr indirection [data] | arrays.cpp:50:8:50:25 | access to array indirection [data] |
| by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | ... = ... |
@@ -411,13 +394,11 @@ edges
| by_reference.cpp:110:8:110:12 | outer indirection [inner_nested, a] | by_reference.cpp:110:14:110:25 | inner_nested indirection [a] |
| by_reference.cpp:110:14:110:25 | inner_nested indirection [a] | by_reference.cpp:110:27:110:27 | a |
| by_reference.cpp:111:8:111:12 | outer indirection [inner_ptr indirection, a] | by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] |
| by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] |
| by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | by_reference.cpp:111:25:111:25 | a |
| by_reference.cpp:112:8:112:12 | outer indirection [a] | by_reference.cpp:112:14:112:14 | a |
| by_reference.cpp:114:8:114:13 | pouter indirection [inner_nested, a] | by_reference.cpp:114:16:114:27 | inner_nested indirection [a] |
| by_reference.cpp:114:16:114:27 | inner_nested indirection [a] | by_reference.cpp:114:29:114:29 | a |
| by_reference.cpp:115:8:115:13 | pouter indirection [inner_ptr indirection, a] | by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] |
| by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] |
| by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | by_reference.cpp:115:27:115:27 | a |
| by_reference.cpp:116:8:116:13 | pouter indirection [a] | by_reference.cpp:116:16:116:16 | a |
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | by_reference.cpp:122:27:122:38 | outer indirection [post update] [inner_nested, a] |
@@ -435,13 +416,11 @@ edges
| by_reference.cpp:130:8:130:12 | outer indirection [inner_nested, a] | by_reference.cpp:130:14:130:25 | inner_nested indirection [a] |
| by_reference.cpp:130:14:130:25 | inner_nested indirection [a] | by_reference.cpp:130:27:130:27 | a |
| by_reference.cpp:131:8:131:12 | outer indirection [inner_ptr indirection, a] | by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] |
| by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] |
| by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | by_reference.cpp:131:25:131:25 | a |
| by_reference.cpp:132:8:132:12 | outer indirection [a] | by_reference.cpp:132:14:132:14 | a |
| by_reference.cpp:134:8:134:13 | pouter indirection [inner_nested, a] | by_reference.cpp:134:16:134:27 | inner_nested indirection [a] |
| by_reference.cpp:134:16:134:27 | inner_nested indirection [a] | by_reference.cpp:134:29:134:29 | a |
| by_reference.cpp:135:8:135:13 | pouter indirection [inner_ptr indirection, a] | by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] |
| by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] |
| by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | by_reference.cpp:135:27:135:27 | a |
| by_reference.cpp:136:8:136:13 | pouter indirection [a] | by_reference.cpp:136:16:136:16 | a |
| clearning.cpp:32:3:32:25 | ... = ... | clearning.cpp:32:6:32:6 | s indirection [post update] [x indirection] |
@@ -460,9 +439,6 @@ edges
| clearning.cpp:54:5:54:5 | s indirection [post update] [x indirection] | clearning.cpp:55:8:55:8 | s indirection [x indirection] |
| clearning.cpp:54:5:54:5 | x indirection | clearning.cpp:54:3:54:7 | ... ++ indirection |
| clearning.cpp:55:8:55:8 | s indirection [x indirection] | clearning.cpp:55:10:55:10 | x indirection |
| clearning.cpp:55:8:55:8 | s indirection [x indirection] | clearning.cpp:55:10:55:10 | x indirection |
| clearning.cpp:55:10:55:10 | x indirection | clearning.cpp:55:10:55:10 | x indirection |
| clearning.cpp:55:10:55:10 | x indirection | clearning.cpp:55:10:55:10 | x indirection |
| clearning.cpp:60:3:60:22 | ... = ... | clearning.cpp:60:7:60:7 | s indirection [post update] [x indirection] |
| clearning.cpp:60:7:60:7 | s indirection [post update] [x indirection] | clearning.cpp:61:3:61:3 | s indirection [x indirection] |
| clearning.cpp:60:11:60:20 | call to user_input | clearning.cpp:60:3:60:22 | ... = ... |
@@ -474,9 +450,6 @@ edges
| clearning.cpp:61:5:61:5 | s indirection [post update] [x indirection] | clearning.cpp:62:8:62:8 | s indirection [x indirection] |
| clearning.cpp:61:5:61:5 | x indirection | clearning.cpp:61:3:61:7 | ... ++ indirection |
| clearning.cpp:62:8:62:8 | s indirection [x indirection] | clearning.cpp:62:10:62:10 | x indirection |
| clearning.cpp:62:8:62:8 | s indirection [x indirection] | clearning.cpp:62:10:62:10 | x indirection |
| clearning.cpp:62:10:62:10 | x indirection | clearning.cpp:62:10:62:10 | x indirection |
| clearning.cpp:62:10:62:10 | x indirection | clearning.cpp:62:10:62:10 | x indirection |
| clearning.cpp:74:20:74:22 | argument_source output argument | clearning.cpp:74:20:74:22 | s indirection [post update] [val indirection] |
| clearning.cpp:74:20:74:22 | s indirection [post update] [val indirection] | clearning.cpp:76:8:76:8 | s indirection [val indirection] |
| clearning.cpp:76:8:76:8 | s indirection [val indirection] | clearning.cpp:76:7:76:12 | * ... |
@@ -620,14 +593,12 @@ edges
| conflated.cpp:54:13:54:13 | next indirection [post update] [y] | conflated.cpp:54:7:54:10 | ll indirection [post update] [next indirection, y] |
| conflated.cpp:54:17:54:26 | call to user_input | conflated.cpp:54:3:54:28 | ... = ... |
| conflated.cpp:55:8:55:9 | ll indirection [next indirection, y] | conflated.cpp:55:12:55:15 | next indirection [y] |
| conflated.cpp:55:12:55:15 | next indirection [y] | conflated.cpp:55:12:55:15 | next indirection [y] |
| conflated.cpp:55:12:55:15 | next indirection [y] | conflated.cpp:55:18:55:18 | y |
| conflated.cpp:60:3:60:28 | ... = ... | conflated.cpp:60:13:60:13 | next indirection [post update] [y] |
| conflated.cpp:60:7:60:10 | ll indirection [post update] [next indirection, y] | conflated.cpp:61:8:61:9 | ll indirection [next indirection, y] |
| conflated.cpp:60:13:60:13 | next indirection [post update] [y] | conflated.cpp:60:7:60:10 | ll indirection [post update] [next indirection, y] |
| conflated.cpp:60:17:60:26 | call to user_input | conflated.cpp:60:3:60:28 | ... = ... |
| conflated.cpp:61:8:61:9 | ll indirection [next indirection, y] | conflated.cpp:61:12:61:15 | next indirection [y] |
| conflated.cpp:61:12:61:15 | next indirection [y] | conflated.cpp:61:12:61:15 | next indirection [y] |
| conflated.cpp:61:12:61:15 | next indirection [y] | conflated.cpp:61:18:61:18 | y |
| constructors.cpp:18:9:18:9 | this indirection [a_] | constructors.cpp:18:22:18:23 | this indirection [a_] |
| constructors.cpp:18:22:18:23 | a_ | constructors.cpp:18:9:18:9 | a indirection |
@@ -672,42 +643,36 @@ edges
| qualifiers.cpp:22:23:22:23 | call to getInner indirection [post update] [a] | qualifiers.cpp:22:5:22:9 | getInner output argument [inner indirection, a] |
| qualifiers.cpp:22:27:22:36 | call to user_input | qualifiers.cpp:22:5:22:38 | ... = ... |
| qualifiers.cpp:23:10:23:14 | outer indirection [inner indirection, a] | qualifiers.cpp:23:16:23:20 | inner indirection [a] |
| qualifiers.cpp:23:16:23:20 | inner indirection [a] | qualifiers.cpp:23:16:23:20 | inner indirection [a] |
| qualifiers.cpp:23:16:23:20 | inner indirection [a] | qualifiers.cpp:23:23:23:23 | a |
| qualifiers.cpp:27:5:27:9 | getInner output argument [inner indirection, a] | qualifiers.cpp:28:10:28:14 | outer indirection [inner indirection, a] |
| qualifiers.cpp:27:11:27:18 | setA output argument [a] | qualifiers.cpp:27:5:27:9 | getInner output argument [inner indirection, a] |
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:9:21:9:25 | value |
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:27:11:27:18 | setA output argument [a] |
| qualifiers.cpp:28:10:28:14 | outer indirection [inner indirection, a] | qualifiers.cpp:28:16:28:20 | inner indirection [a] |
| qualifiers.cpp:28:16:28:20 | inner indirection [a] | qualifiers.cpp:28:16:28:20 | inner indirection [a] |
| qualifiers.cpp:28:16:28:20 | inner indirection [a] | qualifiers.cpp:28:23:28:23 | a |
| qualifiers.cpp:32:17:32:21 | getInner output argument [inner indirection, a] | qualifiers.cpp:33:10:33:14 | outer indirection [inner indirection, a] |
| qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] | qualifiers.cpp:32:17:32:21 | getInner output argument [inner indirection, a] |
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value |
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] |
| qualifiers.cpp:33:10:33:14 | outer indirection [inner indirection, a] | qualifiers.cpp:33:16:33:20 | inner indirection [a] |
| qualifiers.cpp:33:16:33:20 | inner indirection [a] | qualifiers.cpp:33:16:33:20 | inner indirection [a] |
| qualifiers.cpp:33:16:33:20 | inner indirection [a] | qualifiers.cpp:33:23:33:23 | a |
| qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] | qualifiers.cpp:37:20:37:24 | getInner output argument [inner indirection, a] |
| qualifiers.cpp:37:20:37:24 | getInner output argument [inner indirection, a] | qualifiers.cpp:38:10:38:14 | outer indirection [inner indirection, a] |
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value |
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] |
| qualifiers.cpp:38:10:38:14 | outer indirection [inner indirection, a] | qualifiers.cpp:38:16:38:20 | inner indirection [a] |
| qualifiers.cpp:38:16:38:20 | inner indirection [a] | qualifiers.cpp:38:16:38:20 | inner indirection [a] |
| qualifiers.cpp:38:16:38:20 | inner indirection [a] | qualifiers.cpp:38:23:38:23 | a |
| qualifiers.cpp:42:5:42:40 | ... = ... | qualifiers.cpp:42:25:42:25 | * ... indirection [post update] [a] |
| qualifiers.cpp:42:7:42:11 | getInner output argument [inner indirection, a] | qualifiers.cpp:43:10:43:14 | outer indirection [inner indirection, a] |
| qualifiers.cpp:42:25:42:25 | * ... indirection [post update] [a] | qualifiers.cpp:42:7:42:11 | getInner output argument [inner indirection, a] |
| qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:42:5:42:40 | ... = ... |
| qualifiers.cpp:43:10:43:14 | outer indirection [inner indirection, a] | qualifiers.cpp:43:16:43:20 | inner indirection [a] |
| qualifiers.cpp:43:16:43:20 | inner indirection [a] | qualifiers.cpp:43:16:43:20 | inner indirection [a] |
| qualifiers.cpp:43:16:43:20 | inner indirection [a] | qualifiers.cpp:43:23:43:23 | a |
| qualifiers.cpp:47:5:47:42 | ... = ... | qualifiers.cpp:47:27:47:27 | call to getInner indirection [post update] [a] |
| qualifiers.cpp:47:6:47:11 | getInner output argument [inner indirection, a] | qualifiers.cpp:48:10:48:14 | outer indirection [inner indirection, a] |
| qualifiers.cpp:47:27:47:27 | call to getInner indirection [post update] [a] | qualifiers.cpp:47:6:47:11 | getInner output argument [inner indirection, a] |
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:47:5:47:42 | ... = ... |
| qualifiers.cpp:48:10:48:14 | outer indirection [inner indirection, a] | qualifiers.cpp:48:16:48:20 | inner indirection [a] |
| qualifiers.cpp:48:16:48:20 | inner indirection [a] | qualifiers.cpp:48:16:48:20 | inner indirection [a] |
| qualifiers.cpp:48:16:48:20 | inner indirection [a] | qualifiers.cpp:48:23:48:23 | a |
| realistic.cpp:53:9:53:66 | ... = ... | realistic.cpp:53:35:53:43 | userInput indirection [post update] [bufferLen] |
| realistic.cpp:53:13:53:15 | foo indirection [post update] [bar, baz indirection, userInput, bufferLen] | realistic.cpp:61:21:61:23 | foo indirection [bar, baz indirection, userInput, bufferLen] |
@@ -717,7 +682,6 @@ edges
| realistic.cpp:53:47:53:66 | call to user_input | realistic.cpp:53:9:53:66 | ... = ... |
| realistic.cpp:61:21:61:23 | foo indirection [bar, baz indirection, userInput, bufferLen] | realistic.cpp:61:21:61:30 | access to array indirection [baz indirection, userInput, bufferLen] |
| realistic.cpp:61:21:61:30 | access to array indirection [baz indirection, userInput, bufferLen] | realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] |
| realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] |
| realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] |
| realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] | realistic.cpp:61:14:61:55 | bufferLen |
| simple.cpp:18:9:18:9 | this indirection [a_] | simple.cpp:18:22:18:23 | this indirection [a_] |
@@ -796,7 +760,6 @@ edges
| struct_init.c:31:8:31:12 | outer indirection [nestedAB, a] | struct_init.c:31:14:31:21 | nestedAB indirection [a] |
| struct_init.c:31:14:31:21 | nestedAB indirection [a] | struct_init.c:31:23:31:23 | a |
| struct_init.c:33:8:33:12 | outer indirection [pointerAB indirection, a] | struct_init.c:33:14:33:22 | pointerAB indirection [a] |
| struct_init.c:33:14:33:22 | pointerAB indirection [a] | struct_init.c:33:14:33:22 | pointerAB indirection [a] |
| struct_init.c:33:14:33:22 | pointerAB indirection [a] | struct_init.c:33:25:33:25 | a |
| struct_init.c:36:10:36:24 | & ... indirection [a] | struct_init.c:14:24:14:25 | ab indirection [a] |
| struct_init.c:36:11:36:15 | outer indirection [nestedAB, a] | struct_init.c:36:10:36:24 | & ... indirection [a] |
@@ -808,7 +771,6 @@ edges
| struct_init.c:43:5:43:7 | & ... indirection [a] | struct_init.c:41:23:44:3 | definition of outer indirection [post update] [pointerAB indirection, a] |
| struct_init.c:46:10:46:14 | outer indirection [pointerAB indirection, a] | struct_init.c:46:16:46:24 | pointerAB indirection [a] |
| struct_init.c:46:16:46:24 | pointerAB indirection [a] | struct_init.c:14:24:14:25 | ab indirection [a] |
| struct_init.c:46:16:46:24 | pointerAB indirection [a] | struct_init.c:46:16:46:24 | pointerAB indirection [a] |
nodes
| A.cpp:23:10:23:10 | c | semmle.label | c |
| A.cpp:25:7:25:17 | ... = ... | semmle.label | ... = ... |
@@ -1019,7 +981,6 @@ nodes
| E.cpp:21:10:21:10 | p indirection [data, buffer indirection] | semmle.label | p indirection [data, buffer indirection] |
| E.cpp:21:13:21:16 | data indirection [buffer indirection] | semmle.label | data indirection [buffer indirection] |
| E.cpp:21:18:21:23 | buffer indirection | semmle.label | buffer indirection |
| E.cpp:21:18:21:23 | buffer indirection | semmle.label | buffer indirection |
| E.cpp:28:21:28:23 | argument_source output argument | semmle.label | argument_source output argument |
| E.cpp:29:21:29:29 | argument_source output argument | semmle.label | argument_source output argument |
| E.cpp:29:24:29:29 | b indirection [post update] [buffer indirection] | semmle.label | b indirection [post update] [buffer indirection] |
@@ -1029,7 +990,6 @@ nodes
| E.cpp:31:10:31:12 | raw indirection | semmle.label | raw indirection |
| E.cpp:32:10:32:10 | b indirection [buffer indirection] | semmle.label | b indirection [buffer indirection] |
| E.cpp:32:13:32:18 | buffer indirection | semmle.label | buffer indirection |
| E.cpp:32:13:32:18 | buffer indirection | semmle.label | buffer indirection |
| E.cpp:33:18:33:19 | & ... indirection [data, buffer indirection] | semmle.label | & ... indirection [data, buffer indirection] |
| aliasing.cpp:9:3:9:22 | ... = ... | semmle.label | ... = ... |
| aliasing.cpp:9:6:9:7 | s indirection [post update] [m1] | semmle.label | s indirection [post update] [m1] |
@@ -1277,7 +1237,6 @@ nodes
| clearning.cpp:54:5:54:5 | x indirection | semmle.label | x indirection |
| clearning.cpp:55:8:55:8 | s indirection [x indirection] | semmle.label | s indirection [x indirection] |
| clearning.cpp:55:10:55:10 | x indirection | semmle.label | x indirection |
| clearning.cpp:55:10:55:10 | x indirection | semmle.label | x indirection |
| clearning.cpp:60:3:60:22 | ... = ... | semmle.label | ... = ... |
| clearning.cpp:60:7:60:7 | s indirection [post update] [x indirection] | semmle.label | s indirection [post update] [x indirection] |
| clearning.cpp:60:11:60:20 | call to user_input | semmle.label | call to user_input |
@@ -1288,7 +1247,6 @@ nodes
| clearning.cpp:61:5:61:5 | x indirection | semmle.label | x indirection |
| clearning.cpp:62:8:62:8 | s indirection [x indirection] | semmle.label | s indirection [x indirection] |
| clearning.cpp:62:10:62:10 | x indirection | semmle.label | x indirection |
| clearning.cpp:62:10:62:10 | x indirection | semmle.label | x indirection |
| clearning.cpp:74:20:74:22 | argument_source output argument | semmle.label | argument_source output argument |
| clearning.cpp:74:20:74:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] |
| clearning.cpp:76:7:76:12 | * ... | semmle.label | * ... |

View File

@@ -1,2 +1,2 @@
failures
testFailures
failures

View File

@@ -6643,6 +6643,20 @@ WARNING: Module TaintTracking has been deprecated and may be removed in future (
| taint.cpp:729:27:729:32 | endptr | taint.cpp:729:26:729:32 | & ... | |
| taint.cpp:731:7:731:12 | ref arg endptr | taint.cpp:732:8:732:13 | endptr | |
| taint.cpp:732:8:732:13 | endptr | taint.cpp:732:7:732:13 | * ... | TAINT |
| taint.cpp:738:17:738:31 | call to indirect_source | taint.cpp:739:30:739:35 | source | |
| taint.cpp:739:22:739:28 | call to realloc | taint.cpp:740:7:740:10 | dest | |
| taint.cpp:739:30:739:35 | source | taint.cpp:739:22:739:28 | call to realloc | TAINT |
| taint.cpp:743:40:743:45 | buffer | taint.cpp:744:5:744:10 | buffer | |
| taint.cpp:743:40:743:45 | buffer | taint.cpp:745:27:745:32 | buffer | |
| taint.cpp:744:4:744:10 | * ... | taint.cpp:744:3:744:10 | * ... | TAINT |
| taint.cpp:744:5:744:10 | buffer | taint.cpp:744:4:744:10 | * ... | TAINT |
| taint.cpp:744:14:744:19 | call to source | taint.cpp:744:3:744:21 | ... = ... | |
| taint.cpp:745:19:745:25 | call to realloc | taint.cpp:743:40:743:45 | buffer | |
| taint.cpp:745:19:745:25 | call to realloc | taint.cpp:745:3:745:37 | ... = ... | |
| taint.cpp:745:19:745:25 | call to realloc | taint.cpp:746:10:746:15 | buffer | |
| taint.cpp:745:27:745:32 | buffer | taint.cpp:745:19:745:25 | call to realloc | TAINT |
| taint.cpp:746:9:746:15 | * ... | taint.cpp:746:8:746:15 | * ... | TAINT |
| taint.cpp:746:10:746:15 | buffer | taint.cpp:746:9:746:15 | * ... | TAINT |
| vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | |
| vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | |
| vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | |

View File

@@ -730,4 +730,18 @@ void test_strtol(char *source) {
sink(l); // $ ast,ir
sink(endptr); // $ ast,ir
sink(*endptr); // $ ast,ir
}
void *realloc(void *, size_t);
void test_realloc() {
char *source = indirect_source();
char *dest = (char*)realloc(source, 16);
sink(dest); // $ ir MISSING: ast
}
void test_realloc_2_indirections(int **buffer) {
**buffer = source();
buffer = (int**)realloc(buffer, 16);
sink(**buffer); // $ ir MISSING: ast
}

View File

@@ -1,7 +1,7 @@
import cpp
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.ModulusAnalysis
import codeql.rangeanalysis.ModulusAnalysis
import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeUtils
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticLocation
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisRelativeSpecific
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisImpl
@@ -9,8 +9,7 @@ import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
import semmle.code.cpp.ir.IR as IR
import TestUtilities.InlineExpectationsTest
module ModulusAnalysisInstantiated =
ModulusAnalysis<FloatDelta, ConstantBounds, RangeUtil<FloatDelta, CppLangImplRelative>>;
module ModulusAnalysisInstantiated = ModulusAnalysis<SemLocation, Sem, FloatDelta, ConstantBounds>;
module ModulusAnalysisTest implements TestSig {
string getARelevantTag() { result = "mod" }
@@ -31,7 +30,7 @@ import MakeTest<ModulusAnalysisTest>
private string getAModString(SemExpr e) {
exists(SemBound b, int delta, int mod |
ModulusAnalysisInstantiated::semExprModulus(e, b, delta, mod) and
ModulusAnalysisInstantiated::exprModulus(e, b, delta, mod) and
result = b.toString() + "," + delta.toString() + "," + mod.toString() and
not (delta = 0 and mod = 0)
)

View File

@@ -18,7 +18,7 @@ int test2(struct List* p) {
int count = 0;
for (; p; p = p->next) {
count = (count+1) % 10;
range(count); // $ range=<=9 range=>=-9 range="<=Phi: p | Store: count+1"
range(count); // $ range=<=9 range=>=-9
}
range(count); // $ range=>=-9 range=<=9
return count;
@@ -29,7 +29,7 @@ int test3(struct List* p) {
for (; p; p = p->next) {
range(count++); // $ range=>=-9 range=<=9
count = count % 10;
range(count); // $ range=<=9 range=>=-9 range="<=Store: ... +++0" range="<=Phi: p | Store: count+1"
range(count); // $ range=<=9 range=>=-9
}
range(count); // $ range=>=-9 range=<=9
return count;
@@ -317,7 +317,7 @@ int test_mult01(int a, int b) {
range(b); // $ range=<=23 range=>=-13
int r = a*b; // $ overflow=+- -143 .. 253
range(r);
total += r; // $ overflow=+
total += r; // $ overflow=+-
range(total); // $ MISSING: range=">=... * ...+0"
}
if (3 <= a && a <= 11 && -13 <= b && b <= 0) {
@@ -365,7 +365,7 @@ int test_mult02(int a, int b) {
range(b); // $ range=<=23 range=>=-13
int r = a*b; // $ overflow=+- -143 .. 253
range(r);
total += r; // $ overflow=+
total += r; // $ overflow=+-
range(total); // $ MISSING: range=">=... * ...+0"
}
if (0 <= a && a <= 11 && -13 <= b && b <= 0) {
@@ -460,7 +460,7 @@ int test_mult04(int a, int b) {
range(b); // $ range=<=23 range=>=-13
int r = a*b; // $ overflow=+- -391 .. 221
range(r);
total += r; // $ overflow=-
total += r; // $ overflow=+-
range(total); // $ MISSING: range="<=... * ...+0"
}
if (-17 <= a && a <= 0 && -13 <= b && b <= 0) {
@@ -508,7 +508,7 @@ int test_mult05(int a, int b) {
range(b); // $ range=<=23 range=>=-13
int r = a*b; // $ overflow=+- -391 .. 221
range(r);
total += r; // $ overflow=-
total += r; // $ overflow=+-
range(total); // $ MISSING: range="<=... * ...+0"
}
if (-17 <= a && a <= -2 && -13 <= b && b <= 0) {
@@ -974,7 +974,7 @@ void test_mod_neg(int s) {
void test_mod_ternary(int s, bool b) {
int s2 = s % (b ? 5 : 500);
range(s2); // $ range=>=-499 range=<=499 range="<=Phi: ... ? ... : ...-1"
range(s2); // $ range=>=-499 range=<=499
}
void test_mod_ternary2(int s, bool b1, bool b2) {
@@ -1028,4 +1028,73 @@ void test_negate_signed(int s) {
if(10 < s && s < 20) {
range<int>(-s); // $ range=<=-11 range=>=-19
}
}
}
// By setting the guard after the use in another guard we
// don't get the useful information
void test_guard_after_use(int pos, int size, int offset) {
if (pos + offset >= size) { // $ overflow=+-
return;
}
if (offset != 1) {
return;
}
range(pos + 1); // $ overflow=+ range="==InitializeParameter: pos+1" MISSING: range="<=InitializeParameter: size-1"
}
int cond();
// This is basically what we get when we have a loop that calls
// realloc in some iterations
void alloc_in_loop(int origLen) {
if (origLen <= 10) {
return;
}
int len = origLen;
int index = 0;
while (cond()) {
if (index == len) {
if (len >= 1000) {
return;
}
len = len * 2; // $ overflow=-
}
// We want that index < len
range(index); // $ MISSING: range="<=InitializeParameter: len-1"
index++;
}
}
// This came from a case where it handled the leftovers before an unrolled loop
void mask_at_start(int len) {
if (len < 0) {
return;
}
int leftOver = len & 63;
for (int i = 0; i < leftOver; i++) {
range(i); // $ range=<=62 range=>=0 range="<=Store: ... & ... | Store: leftOver-1" range="<=InitializeParameter: len-1"
}
// Do something with leftOver
for (int index = leftOver; index < len; index+=64) {
range(index); // $ range="<=InitializeParameter: len-64" range=">=Store: ... & ... | Store: leftOver+0"
range(index + 63); // $ range="<=InitializeParameter: len-1" range="==Phi: index+63" range=">=Store: ... & ... | Store: leftOver+63"
}
}
// Same as above but with modulo
void mod_at_start(int len) {
if (len < 0) {
return;
}
int leftOver = len % 64;
for (int i = 0; i < leftOver; i++) {
range(i); // $ range=<=62 range=>=0 range="<=Store: ... % ... | Store: leftOver-1" range="<=InitializeParameter: len-1"
}
// Do something with leftOver
for (int index = leftOver; index < len; index+=64) {
range(index); // $ range="<=InitializeParameter: len-64" range=">=Store: ... % ... | Store: leftOver+0"
range(index + 63); // $ range="<=InitializeParameter: len-1" range="==Phi: index+63" range=">=Store: ... % ... | Store: leftOver+63"
}
}

View File

@@ -130,3 +130,19 @@ void test_div(int x) {
range(x >> 2); // $ range=>=0 range=<=2
}
}
struct X { int n; };
void read_argument(const X *);
// This test exists purely to ensure that modulus analysis terminates in the
// presence of inexact phi operands. The LoadInstruction on `while(x->n) { ... }`
// reads from a PhiInstruction with two input operands: an exact operand defined
// by the StoreInstruction generated by `x->n--` and an inexact operand coming
// from the WriteSideEffect generated by `read_argument(x)`. If we don't consider
// the inexact operand modulus analysis fails to terminate.
void nonterminating_without_operands_as_ssa(X *x) {
read_argument(x);
while (x->n) {
x->n--;
}
}

View File

@@ -1,15 +1,13 @@
import cpp
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.SignAnalysisCommon
import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeUtils
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisRelativeSpecific
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
import semmle.code.cpp.ir.IR as IR
import TestUtilities.InlineExpectationsTest
module SignAnalysisInstantiated =
SignAnalysis<FloatDelta, RangeUtil<FloatDelta, CppLangImplRelative>>;
module SignAnalysisInstantiated = SignAnalysis<FloatDelta>;
module SignAnalysisTest implements TestSig {
string getARelevantTag() { result = "sign" }

View File

@@ -4,7 +4,12 @@ uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
| cpp11.cpp:50:15:50:16 | (no string representation) | Node should have one toString but has 0. |
| builtin.c:5:5:5:11 | (no string representation) | Node should have one toString but has 0. |
| misc.c:227:7:227:28 | (no string representation) | Node should have one toString but has 0. |
| static_init_templates.cpp:80:18:80:23 | (no string representation) | Node should have one toString but has 0. |
| static_init_templates.cpp:80:18:80:23 | (no string representation) | Node should have one toString but has 0. |
| static_init_templates.cpp:89:18:89:23 | (no string representation) | Node should have one toString but has 0. |
| static_init_templates.cpp:89:18:89:23 | (no string representation) | Node should have one toString but has 0. |
parameterCallable
localFlowIsLocal
readStepIsLocal

View File

@@ -43,6 +43,11 @@ edges
| test.cpp:189:16:189:16 | p | test.cpp:189:16:189:16 | (reference to) |
| test.cpp:190:10:190:13 | (reference dereference) | test.cpp:190:10:190:13 | (reference to) |
| test.cpp:190:10:190:13 | pRef | test.cpp:190:10:190:13 | (reference dereference) |
| test.cpp:237:12:237:17 | call to alloca | test.cpp:237:12:237:17 | call to alloca |
| test.cpp:237:12:237:17 | call to alloca | test.cpp:238:9:238:9 | p |
| test.cpp:249:13:249:20 | call to strndupa | test.cpp:249:13:249:20 | call to strndupa |
| test.cpp:249:13:249:20 | call to strndupa | test.cpp:250:9:250:10 | s2 |
| test.cpp:250:9:250:10 | s2 | test.cpp:250:9:250:10 | (void *)... |
nodes
| test.cpp:17:9:17:11 | & ... | semmle.label | & ... |
| test.cpp:17:10:17:11 | mc | semmle.label | mc |
@@ -101,6 +106,14 @@ nodes
| test.cpp:190:10:190:13 | (reference dereference) | semmle.label | (reference dereference) |
| test.cpp:190:10:190:13 | (reference to) | semmle.label | (reference to) |
| test.cpp:190:10:190:13 | pRef | semmle.label | pRef |
| test.cpp:237:12:237:17 | call to alloca | semmle.label | call to alloca |
| test.cpp:237:12:237:17 | call to alloca | semmle.label | call to alloca |
| test.cpp:238:9:238:9 | p | semmle.label | p |
| test.cpp:245:9:245:15 | call to strdupa | semmle.label | call to strdupa |
| test.cpp:249:13:249:20 | call to strndupa | semmle.label | call to strndupa |
| test.cpp:249:13:249:20 | call to strndupa | semmle.label | call to strndupa |
| test.cpp:250:9:250:10 | (void *)... | semmle.label | (void *)... |
| test.cpp:250:9:250:10 | s2 | semmle.label | s2 |
#select
| test.cpp:17:9:17:11 | CopyValue: & ... | test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | & ... | May return stack-allocated memory from $@. | test.cpp:17:10:17:11 | mc | mc |
| test.cpp:25:9:25:11 | Load: ptr | test.cpp:23:18:23:19 | mc | test.cpp:25:9:25:11 | ptr | May return stack-allocated memory from $@. | test.cpp:23:18:23:19 | mc | mc |
@@ -115,3 +128,6 @@ nodes
| test.cpp:177:10:177:23 | Convert: (void *)... | test.cpp:176:25:176:34 | localArray | test.cpp:177:10:177:23 | (void *)... | May return stack-allocated memory from $@. | test.cpp:176:25:176:34 | localArray | localArray |
| test.cpp:183:10:183:19 | CopyValue: (reference to) | test.cpp:182:21:182:27 | myLocal | test.cpp:183:10:183:19 | (reference to) | May return stack-allocated memory from $@. | test.cpp:182:21:182:27 | myLocal | myLocal |
| test.cpp:190:10:190:13 | CopyValue: (reference to) | test.cpp:189:16:189:16 | p | test.cpp:190:10:190:13 | (reference to) | May return stack-allocated memory from $@. | test.cpp:189:16:189:16 | p | p |
| test.cpp:238:9:238:9 | Load: p | test.cpp:237:12:237:17 | call to alloca | test.cpp:238:9:238:9 | p | May return stack-allocated memory from $@. | test.cpp:237:12:237:17 | call to alloca | call to alloca |
| test.cpp:245:9:245:15 | Call: call to strdupa | test.cpp:245:9:245:15 | call to strdupa | test.cpp:245:9:245:15 | call to strdupa | May return stack-allocated memory from $@. | test.cpp:245:9:245:15 | call to strdupa | call to strdupa |
| test.cpp:250:9:250:10 | Convert: (void *)... | test.cpp:249:13:249:20 | call to strndupa | test.cpp:250:9:250:10 | (void *)... | May return stack-allocated memory from $@. | test.cpp:249:13:249:20 | call to strndupa | call to strndupa |

View File

@@ -229,4 +229,23 @@ int* id(int* px) {
void f() {
int x;
int* px = id(&x); // GOOD
}
void *alloca(size_t);
void* test_alloca() {
void* p = alloca(10);
return p; // BAD
}
char *strdupa(const char *);
char *strndupa(const char *, size_t);
char* test_strdupa(const char* s) {
return strdupa(s); // BAD
}
void* test_strndupa(const char* s, size_t size) {
char* s2 = strndupa(s, size);
return s2; // BAD
}

View File

@@ -2,11 +2,9 @@ edges
| test.cpp:15:27:15:30 | argv indirection | test.cpp:22:45:22:52 | userName indirection |
| test.cpp:22:13:22:20 | sprintf output argument | test.cpp:23:12:23:19 | command1 indirection |
| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:13:22:20 | sprintf output argument |
| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:45:22:52 | userName indirection |
| test.cpp:47:21:47:26 | call to getenv indirection | test.cpp:50:35:50:43 | envCflags indirection |
| test.cpp:50:11:50:17 | sprintf output argument | test.cpp:51:10:51:16 | command indirection |
| test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:11:50:17 | sprintf output argument |
| test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:35:50:43 | envCflags indirection |
| test.cpp:62:9:62:16 | fread output argument | test.cpp:64:20:64:27 | filename indirection |
| test.cpp:64:11:64:17 | strncat output argument | test.cpp:65:10:65:16 | command indirection |
| test.cpp:64:20:64:27 | filename indirection | test.cpp:64:11:64:17 | strncat output argument |

View File

@@ -4,6 +4,8 @@ edges
| test.c:35:16:35:23 | userName indirection | test.c:40:25:40:32 | username indirection |
| test.c:38:7:38:20 | globalUsername indirection | test.c:51:18:51:23 | query1 indirection |
| test.c:40:25:40:32 | username indirection | test.c:38:7:38:20 | globalUsername indirection |
| test.c:75:8:75:16 | gets output argument | test.c:76:17:76:25 | userInput indirection |
| test.c:75:8:75:16 | gets output argument | test.c:77:20:77:28 | userInput indirection |
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection |
nodes
| test.c:14:27:14:30 | argv indirection | semmle.label | argv indirection |
@@ -12,10 +14,15 @@ nodes
| test.c:38:7:38:20 | globalUsername indirection | semmle.label | globalUsername indirection |
| test.c:40:25:40:32 | username indirection | semmle.label | username indirection |
| test.c:51:18:51:23 | query1 indirection | semmle.label | query1 indirection |
| test.c:75:8:75:16 | gets output argument | semmle.label | gets output argument |
| test.c:76:17:76:25 | userInput indirection | semmle.label | userInput indirection |
| test.c:77:20:77:28 | userInput indirection | semmle.label | userInput indirection |
| test.cpp:39:27:39:30 | argv indirection | semmle.label | argv indirection |
| test.cpp:43:27:43:33 | access to array indirection | semmle.label | access to array indirection |
subpaths
#select
| test.c:21:18:21:23 | query1 | test.c:14:27:14:30 | argv indirection | test.c:21:18:21:23 | query1 indirection | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:14:27:14:30 | argv indirection | user input (a command-line argument) |
| test.c:51:18:51:23 | query1 | test.c:14:27:14:30 | argv indirection | test.c:51:18:51:23 | query1 indirection | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:14:27:14:30 | argv indirection | user input (a command-line argument) |
| test.c:76:17:76:25 | userInput | test.c:75:8:75:16 | gets output argument | test.c:76:17:76:25 | userInput indirection | This argument to a SQL query function is derived from $@ and then passed to SQLPrepare(StatementText). | test.c:75:8:75:16 | gets output argument | user input (string read by gets) |
| test.c:77:20:77:28 | userInput | test.c:75:8:75:16 | gets output argument | test.c:77:20:77:28 | userInput indirection | This argument to a SQL query function is derived from $@ and then passed to SQLExecDirect(StatementText). | test.c:75:8:75:16 | gets output argument | user input (string read by gets) |
| test.cpp:43:27:43:33 | access to array | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)). | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |

View File

@@ -50,3 +50,29 @@ void badFunc() {
snprintf(query1, 1000, "SELECT UID FROM USERS where name = \"%s\"", userName);
mysql_query(0, query1); // BAD
}
//ODBC Library Rountines
typedef unsigned char SQLCHAR;
typedef long int SQLINTEGER;
typedef int SQLRETURN;
typedef void* SQLHSTMT;
char* gets(char *str);
SQLRETURN SQLPrepare(
SQLHSTMT StatementHandle,
SQLCHAR * StatementText,
SQLINTEGER TextLength);
SQLRETURN SQLExecDirect(
SQLHSTMT StatementHandle,
SQLCHAR * StatementText,
SQLINTEGER TextLength);
void ODBCTests(){
char userInput[100];
gets(userInput);
SQLPrepare(0, userInput, 100); // BAD
SQLExecDirect(0, userInput, 100); // BAD
}

View File

@@ -1,23 +1,12 @@
edges
| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data |
| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data |
| test.cpp:37:73:37:76 | data indirection | test.cpp:43:32:43:35 | data |
| test.cpp:37:73:37:76 | data indirection | test.cpp:43:32:43:35 | data |
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data |
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data |
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data indirection |
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data indirection |
| test.cpp:73:24:73:27 | data | test.cpp:37:73:37:76 | data |
| test.cpp:37:73:37:76 | data indirection | test.cpp:43:32:43:35 | data indirection |
| test.cpp:64:30:64:35 | call to getenv indirection | test.cpp:73:24:73:27 | data indirection |
| test.cpp:73:24:73:27 | data indirection | test.cpp:37:73:37:76 | data indirection |
subpaths
nodes
| test.cpp:37:73:37:76 | data | semmle.label | data |
| test.cpp:37:73:37:76 | data indirection | semmle.label | data indirection |
| test.cpp:43:32:43:35 | data | semmle.label | data |
| test.cpp:43:32:43:35 | data | semmle.label | data |
| test.cpp:64:30:64:35 | call to getenv | semmle.label | call to getenv |
| test.cpp:64:30:64:35 | call to getenv | semmle.label | call to getenv |
| test.cpp:73:24:73:27 | data | semmle.label | data |
| test.cpp:43:32:43:35 | data indirection | semmle.label | data indirection |
| test.cpp:64:30:64:35 | call to getenv indirection | semmle.label | call to getenv indirection |
| test.cpp:73:24:73:27 | data indirection | semmle.label | data indirection |
subpaths
#select
| test.cpp:43:32:43:35 | data | test.cpp:64:30:64:35 | call to getenv | test.cpp:43:32:43:35 | data | The value of this argument may come from $@ and is being passed to LoadLibraryA. | test.cpp:64:30:64:35 | call to getenv | call to getenv |
| test.cpp:43:32:43:35 | data indirection | test.cpp:64:30:64:35 | call to getenv indirection | test.cpp:43:32:43:35 | data indirection | The value of this argument may come from $@ and is being passed to LoadLibraryA. | test.cpp:64:30:64:35 | call to getenv indirection | an environment variable |

View File

@@ -1,103 +1,48 @@
edges
| test.cpp:24:30:24:36 | command | test.cpp:26:10:26:16 | command |
| test.cpp:24:30:24:36 | command | test.cpp:26:10:26:16 | command |
| test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command |
| test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command |
| test.cpp:42:18:42:23 | call to getenv | test.cpp:24:30:24:36 | command |
| test.cpp:42:18:42:34 | call to getenv | test.cpp:24:30:24:36 | command |
| test.cpp:43:18:43:23 | call to getenv | test.cpp:29:30:29:36 | command |
| test.cpp:43:18:43:34 | call to getenv | test.cpp:29:30:29:36 | command |
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 |
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer |
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer |
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer |
subpaths
| test.cpp:24:30:24:36 | command indirection | test.cpp:26:10:26:16 | command indirection |
| test.cpp:29:30:29:36 | command indirection | test.cpp:31:10:31:16 | command indirection |
| test.cpp:42:18:42:34 | call to getenv indirection | test.cpp:24:30:24:36 | command indirection |
| test.cpp:43:18:43:34 | call to getenv indirection | test.cpp:29:30:29:36 | command indirection |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer indirection |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data indirection |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | (reference dereference) indirection |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref indirection |
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 indirection |
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer indirection |
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer indirection |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer indirection |
| test.cpp:113:8:113:12 | call to fgets indirection | test.cpp:114:9:114:11 | ptr indirection |
nodes
| test.cpp:24:30:24:36 | command | semmle.label | command |
| test.cpp:26:10:26:16 | command | semmle.label | command |
| test.cpp:26:10:26:16 | command | semmle.label | command |
| test.cpp:29:30:29:36 | command | semmle.label | command |
| test.cpp:31:10:31:16 | command | semmle.label | command |
| test.cpp:31:10:31:16 | command | semmle.label | command |
| test.cpp:42:18:42:23 | call to getenv | semmle.label | call to getenv |
| test.cpp:42:18:42:34 | call to getenv | semmle.label | call to getenv |
| test.cpp:43:18:43:23 | call to getenv | semmle.label | call to getenv |
| test.cpp:43:18:43:34 | call to getenv | semmle.label | call to getenv |
| test.cpp:56:12:56:17 | buffer | semmle.label | buffer |
| test.cpp:56:12:56:17 | buffer | semmle.label | buffer |
| test.cpp:24:30:24:36 | command indirection | semmle.label | command indirection |
| test.cpp:26:10:26:16 | command indirection | semmle.label | command indirection |
| test.cpp:29:30:29:36 | command indirection | semmle.label | command indirection |
| test.cpp:31:10:31:16 | command indirection | semmle.label | command indirection |
| test.cpp:42:18:42:34 | call to getenv indirection | semmle.label | call to getenv indirection |
| test.cpp:43:18:43:34 | call to getenv indirection | semmle.label | call to getenv indirection |
| test.cpp:56:12:56:17 | fgets output argument | semmle.label | fgets output argument |
| test.cpp:62:10:62:15 | buffer | semmle.label | buffer |
| test.cpp:62:10:62:15 | buffer | semmle.label | buffer |
| test.cpp:63:10:63:13 | data | semmle.label | data |
| test.cpp:63:10:63:13 | data | semmle.label | data |
| test.cpp:64:10:64:16 | dataref | semmle.label | dataref |
| test.cpp:64:10:64:16 | dataref | semmle.label | dataref |
| test.cpp:64:10:64:16 | dataref | semmle.label | dataref |
| test.cpp:65:10:65:14 | data2 | semmle.label | data2 |
| test.cpp:65:10:65:14 | data2 | semmle.label | data2 |
| test.cpp:76:12:76:17 | buffer | semmle.label | buffer |
| test.cpp:76:12:76:17 | buffer | semmle.label | buffer |
| test.cpp:62:10:62:15 | buffer indirection | semmle.label | buffer indirection |
| test.cpp:63:10:63:13 | data indirection | semmle.label | data indirection |
| test.cpp:64:10:64:16 | (reference dereference) indirection | semmle.label | (reference dereference) indirection |
| test.cpp:64:10:64:16 | dataref indirection | semmle.label | dataref indirection |
| test.cpp:65:10:65:14 | data2 indirection | semmle.label | data2 indirection |
| test.cpp:76:12:76:17 | fgets output argument | semmle.label | fgets output argument |
| test.cpp:78:10:78:15 | buffer | semmle.label | buffer |
| test.cpp:78:10:78:15 | buffer | semmle.label | buffer |
| test.cpp:98:17:98:22 | buffer | semmle.label | buffer |
| test.cpp:98:17:98:22 | buffer | semmle.label | buffer |
| test.cpp:78:10:78:15 | buffer indirection | semmle.label | buffer indirection |
| test.cpp:98:17:98:22 | recv output argument | semmle.label | recv output argument |
| test.cpp:99:15:99:20 | buffer | semmle.label | buffer |
| test.cpp:99:15:99:20 | buffer | semmle.label | buffer |
| test.cpp:106:17:106:22 | buffer | semmle.label | buffer |
| test.cpp:106:17:106:22 | buffer | semmle.label | buffer |
| test.cpp:99:15:99:20 | buffer indirection | semmle.label | buffer indirection |
| test.cpp:106:17:106:22 | recv output argument | semmle.label | recv output argument |
| test.cpp:107:15:107:20 | buffer | semmle.label | buffer |
| test.cpp:107:15:107:20 | buffer | semmle.label | buffer |
| test.cpp:107:15:107:20 | buffer indirection | semmle.label | buffer indirection |
| test.cpp:113:8:113:12 | call to fgets indirection | semmle.label | call to fgets indirection |
| test.cpp:114:9:114:11 | ptr indirection | semmle.label | ptr indirection |
subpaths
#select
| test.cpp:26:10:26:16 | command | test.cpp:42:18:42:23 | call to getenv | test.cpp:26:10:26:16 | command | The value of this argument may come from $@ and is being passed to system. | test.cpp:42:18:42:23 | call to getenv | call to getenv |
| test.cpp:31:10:31:16 | command | test.cpp:43:18:43:23 | call to getenv | test.cpp:31:10:31:16 | command | The value of this argument may come from $@ and is being passed to system. | test.cpp:43:18:43:23 | call to getenv | call to getenv |
| test.cpp:62:10:62:15 | buffer | test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
| test.cpp:63:10:63:13 | data | test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
| test.cpp:64:10:64:16 | dataref | test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
| test.cpp:65:10:65:14 | data2 | test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
| test.cpp:78:10:78:15 | buffer | test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer | The value of this argument may come from $@ and is being passed to system. | test.cpp:76:12:76:17 | buffer | buffer |
| test.cpp:99:15:99:20 | buffer | test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:98:17:98:22 | buffer | buffer |
| test.cpp:107:15:107:20 | buffer | test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:106:17:106:22 | buffer | buffer |
| test.cpp:26:10:26:16 | command indirection | test.cpp:42:18:42:34 | call to getenv indirection | test.cpp:26:10:26:16 | command indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:42:18:42:34 | call to getenv indirection | an environment variable |
| test.cpp:31:10:31:16 | command indirection | test.cpp:43:18:43:34 | call to getenv indirection | test.cpp:31:10:31:16 | command indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:43:18:43:34 | call to getenv indirection | an environment variable |
| test.cpp:62:10:62:15 | buffer indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
| test.cpp:63:10:63:13 | data indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
| test.cpp:64:10:64:16 | (reference dereference) indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | (reference dereference) indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
| test.cpp:64:10:64:16 | dataref indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
| test.cpp:65:10:65:14 | data2 indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
| test.cpp:78:10:78:15 | buffer indirection | test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:76:12:76:17 | fgets output argument | string read by fgets |
| test.cpp:99:15:99:20 | buffer indirection | test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer indirection | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:98:17:98:22 | recv output argument | buffer read by recv |
| test.cpp:107:15:107:20 | buffer indirection | test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer indirection | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:106:17:106:22 | recv output argument | buffer read by recv |
| test.cpp:114:9:114:11 | ptr indirection | test.cpp:113:8:113:12 | call to fgets indirection | test.cpp:114:9:114:11 | ptr indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:113:8:113:12 | call to fgets indirection | string read by fgets |

View File

@@ -107,3 +107,9 @@ void testAcceptRecv(int socket1, int socket2)
LoadLibrary(buffer); // BAD: using data from recv
}
}
void argumentUse(char *ptr, FILE *stream) {
char buffer[80];
ptr = fgets(buffer, sizeof(buffer), stream);
system(ptr); // BAD
}

View File

@@ -4,7 +4,6 @@ edges
| test.cpp:18:10:18:15 | str indirection [post update] [string] | test.cpp:19:5:19:7 | str indirection [string] |
| test.cpp:18:19:18:24 | call to malloc | test.cpp:18:5:18:30 | ... = ... |
| test.cpp:19:5:19:7 | str indirection [string] | test.cpp:16:11:16:21 | mk_string_t indirection [string] |
| test.cpp:19:5:19:7 | str indirection [string] | test.cpp:19:5:19:7 | str indirection [string] |
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:42:13:42:15 | str indirection [string] |
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:72:17:72:19 | str indirection [string] |
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:80:17:80:19 | str indirection [string] |
@@ -16,7 +15,6 @@ edges
| test.cpp:90:10:90:15 | str indirection [post update] [string] | test.cpp:91:5:91:7 | str indirection [string] |
| test.cpp:90:19:90:24 | call to malloc | test.cpp:90:5:90:34 | ... = ... |
| test.cpp:91:5:91:7 | str indirection [string] | test.cpp:88:11:88:30 | mk_string_t_plus_one indirection [string] |
| test.cpp:91:5:91:7 | str indirection [string] | test.cpp:91:5:91:7 | str indirection [string] |
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:99:13:99:15 | str indirection [string] |
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:129:17:129:19 | str indirection [string] |
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:137:17:137:19 | str indirection [string] |
@@ -26,7 +24,6 @@ edges
| test.cpp:147:5:147:34 | ... = ... | test.cpp:147:10:147:15 | str indirection [post update] [string] |
| test.cpp:147:10:147:15 | str indirection [post update] [string] | test.cpp:148:5:148:7 | str indirection [string] |
| test.cpp:147:19:147:24 | call to malloc | test.cpp:147:5:147:34 | ... = ... |
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:148:5:148:7 | str indirection [string] |
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:152:13:152:15 | str indirection [string] |
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:154:13:154:15 | str indirection [string] |
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:156:13:156:15 | str indirection [string] |

View File

@@ -1,4 +1,32 @@
edges
subpaths
| main.cpp:6:27:6:30 | argv indirection | main.cpp:10:20:10:23 | argv indirection |
| main.cpp:10:20:10:23 | argv indirection | tests.cpp:631:32:631:35 | argv indirection |
| tests.cpp:613:19:613:24 | source indirection | tests.cpp:615:17:615:22 | source indirection |
| tests.cpp:622:19:622:24 | source indirection | tests.cpp:625:2:625:16 | ... = ... indirection |
| tests.cpp:625:2:625:16 | ... = ... indirection | tests.cpp:625:4:625:7 | s indirection [post update] [home indirection] |
| tests.cpp:625:4:625:7 | s indirection [post update] [home indirection] | tests.cpp:628:14:628:14 | s indirection [home indirection] |
| tests.cpp:628:14:628:14 | s indirection [home indirection] | tests.cpp:628:14:628:19 | home indirection |
| tests.cpp:628:14:628:14 | s indirection [home indirection] | tests.cpp:628:16:628:19 | home indirection |
| tests.cpp:628:16:628:19 | home indirection | tests.cpp:628:14:628:19 | home indirection |
| tests.cpp:631:32:631:35 | argv indirection | tests.cpp:656:9:656:15 | access to array indirection |
| tests.cpp:631:32:631:35 | argv indirection | tests.cpp:657:9:657:15 | access to array indirection |
| tests.cpp:656:9:656:15 | access to array indirection | tests.cpp:613:19:613:24 | source indirection |
| tests.cpp:657:9:657:15 | access to array indirection | tests.cpp:622:19:622:24 | source indirection |
nodes
| main.cpp:6:27:6:30 | argv indirection | semmle.label | argv indirection |
| main.cpp:10:20:10:23 | argv indirection | semmle.label | argv indirection |
| tests.cpp:613:19:613:24 | source indirection | semmle.label | source indirection |
| tests.cpp:615:17:615:22 | source indirection | semmle.label | source indirection |
| tests.cpp:622:19:622:24 | source indirection | semmle.label | source indirection |
| tests.cpp:625:2:625:16 | ... = ... indirection | semmle.label | ... = ... indirection |
| tests.cpp:625:4:625:7 | s indirection [post update] [home indirection] | semmle.label | s indirection [post update] [home indirection] |
| tests.cpp:628:14:628:14 | s indirection [home indirection] | semmle.label | s indirection [home indirection] |
| tests.cpp:628:14:628:19 | home indirection | semmle.label | home indirection |
| tests.cpp:628:16:628:19 | home indirection | semmle.label | home indirection |
| tests.cpp:631:32:631:35 | argv indirection | semmle.label | argv indirection |
| tests.cpp:656:9:656:15 | access to array indirection | semmle.label | access to array indirection |
| tests.cpp:657:9:657:15 | access to array indirection | semmle.label | access to array indirection |
subpaths
#select
| tests.cpp:615:2:615:7 | call to strcpy | main.cpp:6:27:6:30 | argv indirection | tests.cpp:615:17:615:22 | source indirection | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | argv indirection | a command-line argument |
| tests.cpp:628:2:628:7 | call to strcpy | main.cpp:6:27:6:30 | argv indirection | tests.cpp:628:14:628:19 | home indirection | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | argv indirection | a command-line argument |

View File

@@ -407,7 +407,7 @@ void test15()
{
if (ptr[5] == ' ') // GOOD
{
// ...
break;
}
}
}
@@ -608,6 +608,26 @@ int test23() {
return sizeof(buffer) / sizeof(buffer[101]); // GOOD
}
char* strcpy(char *, const char *);
void test24(char* source) {
char buffer[100];
strcpy(buffer, source); // BAD
}
struct my_struct {
char* home;
};
void test25(char* source) {
my_struct s;
s.home = source;
char buf[100];
strcpy(buf, s.home); // BAD
}
int tests_main(int argc, char *argv[])
{
long long arr17[19];
@@ -633,6 +653,8 @@ int tests_main(int argc, char *argv[])
test21(argc == 0);
test22(argc == 0, argv[0]);
test23();
test24(argv[0]);
test25(argv[0]);
return 0;
}

View File

@@ -1,37 +1,18 @@
edges
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array |
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array |
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array |
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
subpaths
| tests.c:16:26:16:29 | argv indirection | tests.c:28:22:28:28 | access to array indirection |
| tests.c:16:26:16:29 | argv indirection | tests.c:29:28:29:34 | access to array indirection |
| tests.c:16:26:16:29 | argv indirection | tests.c:34:10:34:16 | access to array indirection |
nodes
| tests.c:28:22:28:25 | argv | semmle.label | argv |
| tests.c:28:22:28:25 | argv | semmle.label | argv |
| tests.c:28:22:28:28 | access to array | semmle.label | access to array |
| tests.c:28:22:28:28 | access to array | semmle.label | access to array |
| tests.c:29:28:29:31 | argv | semmle.label | argv |
| tests.c:29:28:29:31 | argv | semmle.label | argv |
| tests.c:29:28:29:34 | access to array | semmle.label | access to array |
| tests.c:29:28:29:34 | access to array | semmle.label | access to array |
| tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 |
| tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 |
| tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 |
| tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 |
| tests.c:34:10:34:13 | argv | semmle.label | argv |
| tests.c:34:10:34:13 | argv | semmle.label | argv |
| tests.c:34:10:34:16 | access to array | semmle.label | access to array |
| tests.c:34:10:34:16 | access to array | semmle.label | access to array |
| tests.c:16:26:16:29 | argv indirection | semmle.label | argv indirection |
| tests.c:28:22:28:28 | access to array indirection | semmle.label | access to array indirection |
| tests.c:29:28:29:34 | access to array indirection | semmle.label | access to array indirection |
| tests.c:31:15:31:23 | scanf output argument | semmle.label | scanf output argument |
| tests.c:33:21:33:29 | scanf output argument | semmle.label | scanf output argument |
| tests.c:34:10:34:16 | access to array indirection | semmle.label | access to array indirection |
subpaths
#select
| tests.c:28:3:28:9 | call to sprintf | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv |
| tests.c:29:3:29:9 | call to sprintf | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv |
| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | buffer100 | buffer100 |
| tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:33:21:33:29 | buffer100 | buffer100 |
| tests.c:34:25:34:33 | buffer100 | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array | This 'sscanf string argument' with input from $@ may overflow the destination. | tests.c:34:10:34:13 | argv | argv |
| tests.c:28:3:28:9 | call to sprintf | tests.c:16:26:16:29 | argv indirection | tests.c:28:22:28:28 | access to array indirection | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:16:26:16:29 | argv indirection | a command-line argument |
| tests.c:29:3:29:9 | call to sprintf | tests.c:16:26:16:29 | argv indirection | tests.c:29:28:29:34 | access to array indirection | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:16:26:16:29 | argv indirection | a command-line argument |
| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | scanf output argument | tests.c:31:15:31:23 | scanf output argument | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | scanf output argument | value read by scanf |
| tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | scanf output argument | tests.c:33:21:33:29 | scanf output argument | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:33:21:33:29 | scanf output argument | value read by scanf |
| tests.c:34:25:34:33 | buffer100 | tests.c:16:26:16:29 | argv indirection | tests.c:34:10:34:16 | access to array indirection | This 'sscanf string argument' with input from $@ may overflow the destination. | tests.c:16:26:16:29 | argv indirection | a command-line argument |

View File

@@ -1,13 +1,8 @@
edges
| examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data |
| examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data |
| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data |
| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data |
subpaths
nodes
| examples.cpp:63:26:63:30 | & ... | semmle.label | & ... |
| examples.cpp:63:26:63:30 | fscanf output argument | semmle.label | fscanf output argument |
| examples.cpp:66:11:66:14 | data | semmle.label | data |
| examples.cpp:66:11:66:14 | data | semmle.label | data |
subpaths
#select
| examples.cpp:66:11:66:14 | data | examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | examples.cpp:63:26:63:30 | & ... | User-provided value |
| examples.cpp:66:11:66:14 | data | examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | examples.cpp:63:26:63:30 | fscanf output argument | value read by fscanf |

View File

@@ -1,86 +1,59 @@
edges
| test2.cpp:12:21:12:21 | v | test2.cpp:14:11:14:11 | v |
| test2.cpp:12:21:12:21 | v | test2.cpp:14:11:14:11 | v |
| test2.cpp:25:22:25:23 | & ... | test2.cpp:27:13:27:13 | v |
| test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:27:13:27:13 | v |
| test2.cpp:27:13:27:13 | v | test2.cpp:12:21:12:21 | v |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:39:9:39:11 | num |
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:39:9:39:11 | num |
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:40:3:40:5 | num |
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:40:3:40:5 | num |
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:17:6:17:18 | call to getTaintedInt |
| test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections |
| test3.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 |
| test3.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 |
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:17:6:17:18 | call to getTaintedInt |
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:18:6:18:18 | call to getTaintedInt |
| test5.cpp:9:7:9:9 | buf | test5.cpp:5:5:5:17 | getTaintedInt indirection |
| test5.cpp:9:7:9:9 | buf | test5.cpp:5:5:5:17 | getTaintedInt indirection |
| test5.cpp:9:7:9:9 | gets output argument | test5.cpp:5:5:5:17 | getTaintedInt indirection |
| test5.cpp:18:6:18:18 | call to getTaintedInt | test5.cpp:19:6:19:6 | y |
| test5.cpp:18:6:18:18 | call to getTaintedInt | test5.cpp:19:6:19:6 | y |
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
subpaths
| test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections |
| test.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 |
| test.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 |
nodes
| test2.cpp:12:21:12:21 | v | semmle.label | v |
| test2.cpp:14:11:14:11 | v | semmle.label | v |
| test2.cpp:14:11:14:11 | v | semmle.label | v |
| test2.cpp:25:22:25:23 | & ... | semmle.label | & ... |
| test2.cpp:25:22:25:23 | fscanf output argument | semmle.label | fscanf output argument |
| test2.cpp:27:13:27:13 | v | semmle.label | v |
| test2.cpp:36:9:36:14 | buffer | semmle.label | buffer |
| test2.cpp:36:9:36:14 | buffer | semmle.label | buffer |
| test2.cpp:36:9:36:14 | fgets output argument | semmle.label | fgets output argument |
| test2.cpp:39:9:39:11 | num | semmle.label | num |
| test2.cpp:39:9:39:11 | num | semmle.label | num |
| test2.cpp:40:3:40:5 | num | semmle.label | num |
| test2.cpp:40:3:40:5 | num | semmle.label | num |
| test3.c:10:27:10:30 | argv indirection | semmle.label | argv indirection |
| test5.cpp:5:5:5:17 | getTaintedInt indirection | semmle.label | getTaintedInt indirection |
| test5.cpp:9:7:9:9 | buf | semmle.label | buf |
| test5.cpp:9:7:9:9 | buf | semmle.label | buf |
| test5.cpp:9:7:9:9 | gets output argument | semmle.label | gets output argument |
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
| test5.cpp:18:6:18:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
| test5.cpp:19:6:19:6 | y | semmle.label | y |
| test5.cpp:19:6:19:6 | y | semmle.label | y |
| test.c:11:29:11:32 | argv | semmle.label | argv |
| test.c:11:29:11:32 | argv | semmle.label | argv |
| test.c:10:27:10:30 | argv indirection | semmle.label | argv indirection |
| test.c:14:15:14:28 | maxConnections | semmle.label | maxConnections |
| test.c:14:15:14:28 | maxConnections | semmle.label | maxConnections |
| test.c:41:17:41:20 | argv | semmle.label | argv |
| test.c:41:17:41:20 | argv | semmle.label | argv |
| test.c:44:7:44:10 | len2 | semmle.label | len2 |
| test.c:44:7:44:10 | len2 | semmle.label | len2 |
| test.c:51:17:51:20 | argv | semmle.label | argv |
| test.c:51:17:51:20 | argv | semmle.label | argv |
| test.c:54:7:54:10 | len3 | semmle.label | len3 |
| test.c:54:7:54:10 | len3 | semmle.label | len3 |
subpaths
#select
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | & ... | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | & ... | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
| test2.cpp:39:9:39:11 | num | test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | buffer | User-provided value |
| test2.cpp:40:3:40:5 | num | test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | buffer | User-provided value |
| test5.cpp:17:6:17:18 | call to getTaintedInt | test5.cpp:9:7:9:9 | buf | test5.cpp:17:6:17:18 | call to getTaintedInt | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | buf | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | buf | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
| test.c:14:15:14:28 | maxConnections | test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:11:29:11:32 | argv | User-provided value |
| test.c:14:15:14:28 | maxConnections | test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:11:29:11:32 | argv | User-provided value |
| test.c:44:7:44:10 | len2 | test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:41:17:41:20 | argv | User-provided value |
| test.c:54:7:54:10 | len3 | test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:51:17:51:20 | argv | User-provided value |
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
| test2.cpp:39:9:39:11 | num | test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:39:9:39:11 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
| test2.cpp:40:3:40:5 | num | test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:40:3:40:5 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
| test5.cpp:17:6:17:18 | call to getTaintedInt | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:17:6:17:18 | call to getTaintedInt | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:44:7:44:10 | len2 | test3.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:44:7:44:10 | len2 | test3.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:44:7:44:10 | len2 | test.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:44:7:44:10 | len2 | test.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:54:7:54:10 | len3 | test3.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:54:7:54:10 | len3 | test3.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:54:7:54:10 | len3 | test.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
| test.c:54:7:54:10 | len3 | test.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |

View File

@@ -1,9 +1,5 @@
edges
| test.cpp:4:15:4:33 | call to malloc | test.cpp:5:15:5:22 | ... + ... |
| test.cpp:4:15:4:33 | call to malloc | test.cpp:5:15:5:22 | ... + ... |
| test.cpp:4:15:4:33 | call to malloc | test.cpp:6:14:6:15 | * ... |
| test.cpp:4:15:4:33 | call to malloc | test.cpp:6:14:6:15 | * ... |
| test.cpp:4:15:4:33 | call to malloc | test.cpp:8:14:8:21 | * ... |
| test.cpp:5:15:5:22 | ... + ... | test.cpp:5:15:5:22 | ... + ... |
| test.cpp:5:15:5:22 | ... + ... | test.cpp:6:14:6:15 | * ... |
| test.cpp:5:15:5:22 | ... + ... | test.cpp:6:14:6:15 | * ... |
@@ -14,10 +10,6 @@ edges
| test.cpp:6:14:6:15 | * ... | test.cpp:8:14:8:21 | * ... |
| test.cpp:16:15:16:33 | call to malloc | test.cpp:20:14:20:21 | * ... |
| test.cpp:28:15:28:37 | call to malloc | test.cpp:29:15:29:28 | ... + ... |
| test.cpp:28:15:28:37 | call to malloc | test.cpp:29:15:29:28 | ... + ... |
| test.cpp:28:15:28:37 | call to malloc | test.cpp:30:14:30:15 | * ... |
| test.cpp:28:15:28:37 | call to malloc | test.cpp:30:14:30:15 | * ... |
| test.cpp:28:15:28:37 | call to malloc | test.cpp:32:14:32:21 | * ... |
| test.cpp:29:15:29:28 | ... + ... | test.cpp:29:15:29:28 | ... + ... |
| test.cpp:29:15:29:28 | ... + ... | test.cpp:30:14:30:15 | * ... |
| test.cpp:29:15:29:28 | ... + ... | test.cpp:30:14:30:15 | * ... |
@@ -27,29 +19,14 @@ edges
| test.cpp:29:15:29:28 | ... + ... | test.cpp:32:14:32:21 | * ... |
| test.cpp:30:14:30:15 | * ... | test.cpp:32:14:32:21 | * ... |
| test.cpp:51:33:51:35 | end | test.cpp:60:34:60:37 | mk_array output argument |
| test.cpp:52:19:52:37 | call to malloc | test.cpp:53:5:53:23 | ... = ... |
| test.cpp:52:19:52:37 | call to malloc | test.cpp:53:12:53:23 | ... + ... |
| test.cpp:53:5:53:23 | ... = ... | test.cpp:51:33:51:35 | end |
| test.cpp:53:12:53:23 | ... + ... | test.cpp:53:5:53:23 | ... = ... |
| test.cpp:53:12:53:23 | ... + ... | test.cpp:51:33:51:35 | end |
| test.cpp:60:34:60:37 | mk_array output argument | test.cpp:67:9:67:14 | ... = ... |
| test.cpp:194:15:194:33 | call to malloc | test.cpp:195:17:195:23 | ... + ... |
| test.cpp:194:15:194:33 | call to malloc | test.cpp:195:17:195:23 | ... + ... |
| test.cpp:194:15:194:33 | call to malloc | test.cpp:201:5:201:19 | ... = ... |
| test.cpp:195:17:195:23 | ... + ... | test.cpp:195:17:195:23 | ... + ... |
| test.cpp:195:17:195:23 | ... + ... | test.cpp:201:5:201:19 | ... = ... |
| test.cpp:195:17:195:23 | ... + ... | test.cpp:201:5:201:19 | ... = ... |
| test.cpp:205:15:205:33 | call to malloc | test.cpp:206:17:206:23 | ... + ... |
| test.cpp:205:15:205:33 | call to malloc | test.cpp:206:17:206:23 | ... + ... |
| test.cpp:205:15:205:33 | call to malloc | test.cpp:213:5:213:13 | ... = ... |
| test.cpp:206:17:206:23 | ... + ... | test.cpp:206:17:206:23 | ... + ... |
| test.cpp:206:17:206:23 | ... + ... | test.cpp:213:5:213:13 | ... = ... |
| test.cpp:206:17:206:23 | ... + ... | test.cpp:213:5:213:13 | ... = ... |
| test.cpp:231:18:231:30 | new[] | test.cpp:232:3:232:20 | ... = ... |
| test.cpp:238:20:238:32 | new[] | test.cpp:239:5:239:22 | ... = ... |
| test.cpp:260:13:260:24 | new[] | test.cpp:261:14:261:21 | ... + ... |
| test.cpp:260:13:260:24 | new[] | test.cpp:261:14:261:21 | ... + ... |
| test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | * ... |
| test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | * ... |
| test.cpp:261:14:261:21 | ... + ... | test.cpp:261:14:261:21 | ... + ... |
| test.cpp:261:14:261:21 | ... + ... | test.cpp:264:13:264:14 | * ... |
| test.cpp:261:14:261:21 | ... + ... | test.cpp:264:13:264:14 | * ... |
@@ -58,107 +35,48 @@ edges
| test.cpp:264:13:264:14 | * ... | test.cpp:264:13:264:14 | * ... |
| test.cpp:264:13:264:14 | * ... | test.cpp:264:13:264:14 | * ... |
| test.cpp:270:13:270:24 | new[] | test.cpp:271:14:271:21 | ... + ... |
| test.cpp:270:13:270:24 | new[] | test.cpp:271:14:271:21 | ... + ... |
| test.cpp:270:13:270:24 | new[] | test.cpp:274:5:274:10 | ... = ... |
| test.cpp:271:14:271:21 | ... + ... | test.cpp:271:14:271:21 | ... + ... |
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... |
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... |
| test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:23 | ... + ... |
| test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:23 | ... + ... |
| test.cpp:355:14:355:27 | new[] | test.cpp:357:24:357:30 | ... + ... |
| test.cpp:355:14:355:27 | new[] | test.cpp:357:24:357:30 | ... + ... |
| test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | end_plus_one indirection |
| test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | ... + ... indirection |
| test.cpp:356:15:356:23 | ... + ... | test.cpp:356:15:356:23 | ... + ... |
| test.cpp:356:15:356:23 | ... + ... | test.cpp:358:14:358:26 | end_plus_one indirection |
| test.cpp:356:15:356:23 | ... + ... | test.cpp:358:14:358:26 | end_plus_one indirection |
| test.cpp:356:15:356:23 | ... + ... | test.cpp:359:14:359:32 | ... + ... indirection |
| test.cpp:356:15:356:23 | ... + ... | test.cpp:359:14:359:32 | ... + ... indirection |
| test.cpp:357:24:357:30 | ... + ... | test.cpp:357:24:357:30 | ... + ... |
| test.cpp:357:24:357:30 | ... + ... | test.cpp:358:14:358:26 | end_plus_one indirection |
| test.cpp:357:24:357:30 | ... + ... | test.cpp:358:14:358:26 | end_plus_one indirection |
| test.cpp:357:24:357:30 | ... + ... | test.cpp:359:14:359:32 | ... + ... indirection |
| test.cpp:357:24:357:30 | ... + ... | test.cpp:359:14:359:32 | ... + ... indirection |
| test.cpp:377:14:377:27 | new[] | test.cpp:378:15:378:23 | ... + ... |
| test.cpp:377:14:377:27 | new[] | test.cpp:378:15:378:23 | ... + ... |
| test.cpp:377:14:377:27 | new[] | test.cpp:381:5:381:9 | ... ++ |
| test.cpp:377:14:377:27 | new[] | test.cpp:381:5:381:9 | ... ++ |
| test.cpp:377:14:377:27 | new[] | test.cpp:384:13:384:16 | end indirection |
| test.cpp:378:15:378:23 | ... + ... | test.cpp:378:15:378:23 | ... + ... |
| test.cpp:378:15:378:23 | ... + ... | test.cpp:384:13:384:16 | end indirection |
| test.cpp:378:15:378:23 | ... + ... | test.cpp:384:13:384:16 | end indirection |
| test.cpp:381:5:381:9 | ... ++ | test.cpp:381:5:381:9 | ... ++ |
| test.cpp:381:5:381:9 | ... ++ | test.cpp:384:13:384:16 | end indirection |
| test.cpp:410:14:410:27 | new[] | test.cpp:411:15:411:23 | & ... |
| test.cpp:410:14:410:27 | new[] | test.cpp:411:15:411:23 | & ... |
| test.cpp:410:14:410:27 | new[] | test.cpp:413:5:413:8 | ... ++ |
| test.cpp:410:14:410:27 | new[] | test.cpp:413:5:413:8 | ... ++ |
| test.cpp:410:14:410:27 | new[] | test.cpp:415:7:415:15 | ... = ... |
| test.cpp:411:15:411:23 | & ... | test.cpp:411:15:411:23 | & ... |
| test.cpp:411:15:411:23 | & ... | test.cpp:415:7:415:15 | ... = ... |
| test.cpp:411:15:411:23 | & ... | test.cpp:415:7:415:15 | ... = ... |
| test.cpp:413:5:413:8 | ... ++ | test.cpp:413:5:413:8 | ... ++ |
| test.cpp:413:5:413:8 | ... ++ | test.cpp:415:7:415:15 | ... = ... |
| test.cpp:413:5:413:8 | ... ++ | test.cpp:415:7:415:15 | ... = ... |
| test.cpp:421:14:421:27 | new[] | test.cpp:422:15:422:23 | & ... |
| test.cpp:421:14:421:27 | new[] | test.cpp:422:15:422:23 | & ... |
| test.cpp:421:14:421:27 | new[] | test.cpp:424:5:424:8 | ... ++ |
| test.cpp:421:14:421:27 | new[] | test.cpp:424:5:424:8 | ... ++ |
| test.cpp:421:14:421:27 | new[] | test.cpp:426:7:426:15 | ... = ... |
| test.cpp:422:15:422:23 | & ... | test.cpp:422:15:422:23 | & ... |
| test.cpp:422:15:422:23 | & ... | test.cpp:426:7:426:15 | ... = ... |
| test.cpp:422:15:422:23 | & ... | test.cpp:426:7:426:15 | ... = ... |
| test.cpp:424:5:424:8 | ... ++ | test.cpp:424:5:424:8 | ... ++ |
| test.cpp:424:5:424:8 | ... ++ | test.cpp:426:7:426:15 | ... = ... |
| test.cpp:424:5:424:8 | ... ++ | test.cpp:426:7:426:15 | ... = ... |
| test.cpp:432:14:432:27 | new[] | test.cpp:433:15:433:23 | & ... |
| test.cpp:432:14:432:27 | new[] | test.cpp:433:15:433:23 | & ... |
| test.cpp:432:14:432:27 | new[] | test.cpp:436:5:436:8 | ... ++ |
| test.cpp:432:14:432:27 | new[] | test.cpp:436:5:436:8 | ... ++ |
| test.cpp:432:14:432:27 | new[] | test.cpp:438:7:438:15 | ... = ... |
| test.cpp:433:15:433:23 | & ... | test.cpp:433:15:433:23 | & ... |
| test.cpp:433:15:433:23 | & ... | test.cpp:438:7:438:15 | ... = ... |
| test.cpp:433:15:433:23 | & ... | test.cpp:438:7:438:15 | ... = ... |
| test.cpp:436:5:436:8 | ... ++ | test.cpp:436:5:436:8 | ... ++ |
| test.cpp:436:5:436:8 | ... ++ | test.cpp:438:7:438:15 | ... = ... |
| test.cpp:436:5:436:8 | ... ++ | test.cpp:438:7:438:15 | ... = ... |
| test.cpp:444:14:444:27 | new[] | test.cpp:445:15:445:23 | & ... |
| test.cpp:444:14:444:27 | new[] | test.cpp:445:15:445:23 | & ... |
| test.cpp:444:14:444:27 | new[] | test.cpp:448:5:448:8 | ... ++ |
| test.cpp:444:14:444:27 | new[] | test.cpp:448:5:448:8 | ... ++ |
| test.cpp:444:14:444:27 | new[] | test.cpp:450:7:450:15 | ... = ... |
| test.cpp:445:15:445:23 | & ... | test.cpp:445:15:445:23 | & ... |
| test.cpp:445:15:445:23 | & ... | test.cpp:450:7:450:15 | ... = ... |
| test.cpp:445:15:445:23 | & ... | test.cpp:450:7:450:15 | ... = ... |
| test.cpp:448:5:448:8 | ... ++ | test.cpp:448:5:448:8 | ... ++ |
| test.cpp:448:5:448:8 | ... ++ | test.cpp:450:7:450:15 | ... = ... |
| test.cpp:448:5:448:8 | ... ++ | test.cpp:450:7:450:15 | ... = ... |
| test.cpp:480:14:480:27 | new[] | test.cpp:481:15:481:23 | & ... |
| test.cpp:480:14:480:27 | new[] | test.cpp:481:15:481:23 | & ... |
| test.cpp:480:14:480:27 | new[] | test.cpp:484:5:484:8 | ... ++ |
| test.cpp:480:14:480:27 | new[] | test.cpp:484:5:484:8 | ... ++ |
| test.cpp:480:14:480:27 | new[] | test.cpp:486:7:486:15 | ... = ... |
| test.cpp:481:15:481:23 | & ... | test.cpp:481:15:481:23 | & ... |
| test.cpp:481:15:481:23 | & ... | test.cpp:486:7:486:15 | ... = ... |
| test.cpp:481:15:481:23 | & ... | test.cpp:486:7:486:15 | ... = ... |
| test.cpp:484:5:484:8 | ... ++ | test.cpp:484:5:484:8 | ... ++ |
| test.cpp:484:5:484:8 | ... ++ | test.cpp:486:7:486:15 | ... = ... |
| test.cpp:484:5:484:8 | ... ++ | test.cpp:486:7:486:15 | ... = ... |
| test.cpp:543:14:543:27 | new[] | test.cpp:548:5:548:19 | ... = ... |
| test.cpp:554:14:554:27 | new[] | test.cpp:559:5:559:19 | ... = ... |
| test.cpp:642:14:642:31 | new[] | test.cpp:647:5:647:19 | ... = ... |
| test.cpp:695:13:695:26 | new[] | test.cpp:698:5:698:10 | ... += ... |
| test.cpp:695:13:695:26 | new[] | test.cpp:698:5:698:10 | ... += ... |
| test.cpp:698:5:698:10 | ... += ... | test.cpp:698:5:698:10 | ... += ... |
| test.cpp:698:5:698:10 | ... += ... | test.cpp:701:15:701:16 | p indirection |
| test.cpp:705:18:705:18 | q | test.cpp:705:18:705:18 | q |
| test.cpp:705:18:705:18 | q | test.cpp:706:12:706:13 | * ... |
| test.cpp:705:18:705:18 | q | test.cpp:706:12:706:13 | * ... |
| test.cpp:711:13:711:26 | new[] | test.cpp:714:11:714:11 | q |
| test.cpp:714:11:714:11 | q | test.cpp:705:18:705:18 | q |
| test.cpp:730:12:730:28 | new[] | test.cpp:732:16:732:26 | ... + ... |
| test.cpp:730:12:730:28 | new[] | test.cpp:732:16:732:26 | ... + ... |
| test.cpp:730:12:730:28 | new[] | test.cpp:733:5:733:12 | ... = ... |
| test.cpp:732:16:732:26 | ... + ... | test.cpp:732:16:732:26 | ... + ... |
| test.cpp:732:16:732:26 | ... + ... | test.cpp:733:5:733:12 | ... = ... |
| test.cpp:732:16:732:26 | ... + ... | test.cpp:733:5:733:12 | ... = ... |
@@ -169,10 +87,8 @@ edges
| test.cpp:781:14:781:27 | new[] | test.cpp:786:18:786:27 | access to array |
| test.cpp:792:60:792:62 | end | test.cpp:800:40:800:43 | mk_array_no_field_flow output argument |
| test.cpp:792:60:792:62 | end | test.cpp:832:40:832:43 | mk_array_no_field_flow output argument |
| test.cpp:793:14:793:32 | call to malloc | test.cpp:794:5:794:24 | ... = ... |
| test.cpp:793:14:793:32 | call to malloc | test.cpp:794:12:794:24 | ... + ... |
| test.cpp:794:5:794:24 | ... = ... | test.cpp:792:60:792:62 | end |
| test.cpp:794:12:794:24 | ... + ... | test.cpp:794:5:794:24 | ... = ... |
| test.cpp:794:12:794:24 | ... + ... | test.cpp:792:60:792:62 | end |
| test.cpp:800:40:800:43 | mk_array_no_field_flow output argument | test.cpp:807:7:807:12 | ... = ... |
| test.cpp:815:52:815:54 | end | test.cpp:815:52:815:54 | end |
| test.cpp:815:52:815:54 | end | test.cpp:821:7:821:12 | ... = ... |
@@ -182,8 +98,6 @@ edges
| test.cpp:841:18:841:35 | call to malloc | test.cpp:842:3:842:20 | ... = ... |
| test.cpp:848:20:848:37 | call to malloc | test.cpp:849:5:849:22 | ... = ... |
| test.cpp:856:12:856:35 | call to malloc | test.cpp:857:16:857:29 | ... + ... |
| test.cpp:856:12:856:35 | call to malloc | test.cpp:857:16:857:29 | ... + ... |
| test.cpp:856:12:856:35 | call to malloc | test.cpp:860:5:860:11 | ... = ... |
| test.cpp:857:16:857:29 | ... + ... | test.cpp:857:16:857:29 | ... + ... |
| test.cpp:857:16:857:29 | ... + ... | test.cpp:860:5:860:11 | ... = ... |
| test.cpp:857:16:857:29 | ... + ... | test.cpp:860:5:860:11 | ... = ... |
@@ -204,22 +118,13 @@ nodes
| test.cpp:32:14:32:21 | * ... | semmle.label | * ... |
| test.cpp:51:33:51:35 | end | semmle.label | end |
| test.cpp:52:19:52:37 | call to malloc | semmle.label | call to malloc |
| test.cpp:53:5:53:23 | ... = ... | semmle.label | ... = ... |
| test.cpp:53:12:53:23 | ... + ... | semmle.label | ... + ... |
| test.cpp:60:34:60:37 | mk_array output argument | semmle.label | mk_array output argument |
| test.cpp:67:9:67:14 | ... = ... | semmle.label | ... = ... |
| test.cpp:194:15:194:33 | call to malloc | semmle.label | call to malloc |
| test.cpp:195:17:195:23 | ... + ... | semmle.label | ... + ... |
| test.cpp:195:17:195:23 | ... + ... | semmle.label | ... + ... |
| test.cpp:201:5:201:19 | ... = ... | semmle.label | ... = ... |
| test.cpp:205:15:205:33 | call to malloc | semmle.label | call to malloc |
| test.cpp:206:17:206:23 | ... + ... | semmle.label | ... + ... |
| test.cpp:206:17:206:23 | ... + ... | semmle.label | ... + ... |
| test.cpp:213:5:213:13 | ... = ... | semmle.label | ... = ... |
| test.cpp:231:18:231:30 | new[] | semmle.label | new[] |
| test.cpp:232:3:232:20 | ... = ... | semmle.label | ... = ... |
| test.cpp:238:20:238:32 | new[] | semmle.label | new[] |
| test.cpp:239:5:239:22 | ... = ... | semmle.label | ... = ... |
| test.cpp:260:13:260:24 | new[] | semmle.label | new[] |
| test.cpp:261:14:261:21 | ... + ... | semmle.label | ... + ... |
| test.cpp:261:14:261:21 | ... + ... | semmle.label | ... + ... |
@@ -232,45 +137,31 @@ nodes
| test.cpp:355:14:355:27 | new[] | semmle.label | new[] |
| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... |
| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... |
| test.cpp:357:24:357:30 | ... + ... | semmle.label | ... + ... |
| test.cpp:357:24:357:30 | ... + ... | semmle.label | ... + ... |
| test.cpp:358:14:358:26 | end_plus_one indirection | semmle.label | end_plus_one indirection |
| test.cpp:359:14:359:32 | ... + ... indirection | semmle.label | ... + ... indirection |
| test.cpp:377:14:377:27 | new[] | semmle.label | new[] |
| test.cpp:378:15:378:23 | ... + ... | semmle.label | ... + ... |
| test.cpp:378:15:378:23 | ... + ... | semmle.label | ... + ... |
| test.cpp:381:5:381:9 | ... ++ | semmle.label | ... ++ |
| test.cpp:381:5:381:9 | ... ++ | semmle.label | ... ++ |
| test.cpp:384:13:384:16 | end indirection | semmle.label | end indirection |
| test.cpp:410:14:410:27 | new[] | semmle.label | new[] |
| test.cpp:411:15:411:23 | & ... | semmle.label | & ... |
| test.cpp:411:15:411:23 | & ... | semmle.label | & ... |
| test.cpp:413:5:413:8 | ... ++ | semmle.label | ... ++ |
| test.cpp:413:5:413:8 | ... ++ | semmle.label | ... ++ |
| test.cpp:415:7:415:15 | ... = ... | semmle.label | ... = ... |
| test.cpp:421:14:421:27 | new[] | semmle.label | new[] |
| test.cpp:422:15:422:23 | & ... | semmle.label | & ... |
| test.cpp:422:15:422:23 | & ... | semmle.label | & ... |
| test.cpp:424:5:424:8 | ... ++ | semmle.label | ... ++ |
| test.cpp:424:5:424:8 | ... ++ | semmle.label | ... ++ |
| test.cpp:426:7:426:15 | ... = ... | semmle.label | ... = ... |
| test.cpp:432:14:432:27 | new[] | semmle.label | new[] |
| test.cpp:433:15:433:23 | & ... | semmle.label | & ... |
| test.cpp:433:15:433:23 | & ... | semmle.label | & ... |
| test.cpp:436:5:436:8 | ... ++ | semmle.label | ... ++ |
| test.cpp:436:5:436:8 | ... ++ | semmle.label | ... ++ |
| test.cpp:438:7:438:15 | ... = ... | semmle.label | ... = ... |
| test.cpp:444:14:444:27 | new[] | semmle.label | new[] |
| test.cpp:445:15:445:23 | & ... | semmle.label | & ... |
| test.cpp:445:15:445:23 | & ... | semmle.label | & ... |
| test.cpp:448:5:448:8 | ... ++ | semmle.label | ... ++ |
| test.cpp:448:5:448:8 | ... ++ | semmle.label | ... ++ |
| test.cpp:450:7:450:15 | ... = ... | semmle.label | ... = ... |
| test.cpp:480:14:480:27 | new[] | semmle.label | new[] |
| test.cpp:481:15:481:23 | & ... | semmle.label | & ... |
| test.cpp:481:15:481:23 | & ... | semmle.label | & ... |
| test.cpp:484:5:484:8 | ... ++ | semmle.label | ... ++ |
| test.cpp:484:5:484:8 | ... ++ | semmle.label | ... ++ |
| test.cpp:486:7:486:15 | ... = ... | semmle.label | ... = ... |
| test.cpp:543:14:543:27 | new[] | semmle.label | new[] |
| test.cpp:548:5:548:19 | ... = ... | semmle.label | ... = ... |
@@ -278,15 +169,6 @@ nodes
| test.cpp:559:5:559:19 | ... = ... | semmle.label | ... = ... |
| test.cpp:642:14:642:31 | new[] | semmle.label | new[] |
| test.cpp:647:5:647:19 | ... = ... | semmle.label | ... = ... |
| test.cpp:695:13:695:26 | new[] | semmle.label | new[] |
| test.cpp:698:5:698:10 | ... += ... | semmle.label | ... += ... |
| test.cpp:698:5:698:10 | ... += ... | semmle.label | ... += ... |
| test.cpp:701:15:701:16 | p indirection | semmle.label | p indirection |
| test.cpp:705:18:705:18 | q | semmle.label | q |
| test.cpp:705:18:705:18 | q | semmle.label | q |
| test.cpp:706:12:706:13 | * ... | semmle.label | * ... |
| test.cpp:711:13:711:26 | new[] | semmle.label | new[] |
| test.cpp:714:11:714:11 | q | semmle.label | q |
| test.cpp:730:12:730:28 | new[] | semmle.label | new[] |
| test.cpp:732:16:732:26 | ... + ... | semmle.label | ... + ... |
| test.cpp:732:16:732:26 | ... + ... | semmle.label | ... + ... |
@@ -300,7 +182,6 @@ nodes
| test.cpp:786:18:786:27 | access to array | semmle.label | access to array |
| test.cpp:792:60:792:62 | end | semmle.label | end |
| test.cpp:793:14:793:32 | call to malloc | semmle.label | call to malloc |
| test.cpp:794:5:794:24 | ... = ... | semmle.label | ... = ... |
| test.cpp:794:12:794:24 | ... + ... | semmle.label | ... + ... |
| test.cpp:800:40:800:43 | mk_array_no_field_flow output argument | semmle.label | mk_array_no_field_flow output argument |
| test.cpp:807:7:807:12 | ... = ... | semmle.label | ... = ... |
@@ -325,10 +206,7 @@ subpaths
| test.cpp:30:14:30:15 | * ... | test.cpp:28:15:28:37 | call to malloc | test.cpp:30:14:30:15 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:28:15:28:37 | call to malloc | call to malloc | test.cpp:29:20:29:27 | ... + ... | ... + ... |
| test.cpp:32:14:32:21 | * ... | test.cpp:28:15:28:37 | call to malloc | test.cpp:32:14:32:21 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:28:15:28:37 | call to malloc | call to malloc | test.cpp:29:20:29:27 | ... + ... | ... + ... |
| test.cpp:67:9:67:14 | ... = ... | test.cpp:52:19:52:37 | call to malloc | test.cpp:67:9:67:14 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:52:19:52:37 | call to malloc | call to malloc | test.cpp:53:20:53:23 | size | size |
| test.cpp:201:5:201:19 | ... = ... | test.cpp:194:15:194:33 | call to malloc | test.cpp:201:5:201:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:194:15:194:33 | call to malloc | call to malloc | test.cpp:195:21:195:23 | len | len |
| test.cpp:213:5:213:13 | ... = ... | test.cpp:205:15:205:33 | call to malloc | test.cpp:213:5:213:13 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:205:15:205:33 | call to malloc | call to malloc | test.cpp:206:21:206:23 | len | len |
| test.cpp:232:3:232:20 | ... = ... | test.cpp:231:18:231:30 | new[] | test.cpp:232:3:232:20 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:231:18:231:30 | new[] | new[] | test.cpp:232:11:232:15 | index | index |
| test.cpp:239:5:239:22 | ... = ... | test.cpp:238:20:238:32 | new[] | test.cpp:239:5:239:22 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:238:20:238:32 | new[] | new[] | test.cpp:239:13:239:17 | index | index |
| test.cpp:264:13:264:14 | * ... | test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:260:13:260:24 | new[] | new[] | test.cpp:261:19:261:21 | len | len |
| test.cpp:274:5:274:10 | ... = ... | test.cpp:270:13:270:24 | new[] | test.cpp:274:5:274:10 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:270:13:270:24 | new[] | new[] | test.cpp:271:19:271:21 | len | len |
| test.cpp:358:14:358:26 | end_plus_one indirection | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | end_plus_one indirection | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size |
@@ -342,8 +220,6 @@ subpaths
| test.cpp:548:5:548:19 | ... = ... | test.cpp:543:14:543:27 | new[] | test.cpp:548:5:548:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:543:14:543:27 | new[] | new[] | test.cpp:548:8:548:14 | src_pos | src_pos |
| test.cpp:559:5:559:19 | ... = ... | test.cpp:554:14:554:27 | new[] | test.cpp:559:5:559:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:554:14:554:27 | new[] | new[] | test.cpp:559:8:559:14 | src_pos | src_pos |
| test.cpp:647:5:647:19 | ... = ... | test.cpp:642:14:642:31 | new[] | test.cpp:647:5:647:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:642:14:642:31 | new[] | new[] | test.cpp:647:8:647:14 | src_pos | src_pos |
| test.cpp:701:15:701:16 | p indirection | test.cpp:695:13:695:26 | new[] | test.cpp:701:15:701:16 | p indirection | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:695:13:695:26 | new[] | new[] | test.cpp:696:19:696:22 | size | size |
| test.cpp:706:12:706:13 | * ... | test.cpp:711:13:711:26 | new[] | test.cpp:706:12:706:13 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:711:13:711:26 | new[] | new[] | test.cpp:712:19:712:22 | size | size |
| test.cpp:733:5:733:12 | ... = ... | test.cpp:730:12:730:28 | new[] | test.cpp:733:5:733:12 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:730:12:730:28 | new[] | new[] | test.cpp:732:21:732:25 | ... + ... | ... + ... |
| test.cpp:767:16:767:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:767:16:767:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:767:22:767:28 | ... + ... | ... + ... |
| test.cpp:767:16:767:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:767:16:767:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:772:22:772:28 | ... + ... | ... + ... |

View File

@@ -3,9 +3,9 @@ using size_t = decltype(sizeof 0); void* malloc(size_t size);
void test1(int size) {
char* p = (char*)malloc(size);
char* q = p + size; // $ alloc=L4
char a = *q; // $ deref=L6 // BAD
char a = *q; // $ deref=L5->L6 // BAD
char b = *(q - 1); // GOOD
char c = *(q + 1); // $ deref=L8+1 // BAD
char c = *(q + 1); // $ deref=L5->L8+1 // BAD
char d = *(q + size); // BAD [NOT DETECTED]
char e = *(q - size); // GOOD
char f = *(q + size + 1); // BAD [NOT DETECTED]
@@ -17,7 +17,7 @@ void test2(int size) {
char* q = p + size - 1; // $ alloc=L16
char a = *q; // GOOD
char b = *(q - 1); // GOOD
char c = *(q + 1); // $ deref=L20 // BAD
char c = *(q + 1); // $ deref=L17->L20 // BAD
char d = *(q + size); // BAD [NOT DETECTED]
char e = *(q - size); // GOOD
char f = *(q + size + 1); // BAD [NOT DETECTED]
@@ -27,9 +27,9 @@ void test2(int size) {
void test3(int size) {
char* p = (char*)malloc(size + 1);
char* q = p + (size + 1); // $ alloc=L28+1
char a = *q; // $ deref=L30 // BAD
char a = *q; // $ deref=L29->L30 // BAD
char b = *(q - 1); // GOOD
char c = *(q + 1); // $ deref=L32+1 // BAD
char c = *(q + 1); // $ deref=L29->L32+1 // BAD
char d = *(q + size); // BAD [NOT DETECTED]
char e = *(q - size); // GOOD
char f = *(q + size + 1); // BAD [NOT DETECTED]
@@ -198,7 +198,7 @@ void test12(unsigned len, unsigned index) {
return;
}
p[index] = '\0'; // $ deref=L201 // BAD
p[index] = '\0'; // $ MISSING: deref=L195->L201 // BAD [NOT DETECTED]
}
void test13(unsigned len, unsigned index) {
@@ -210,7 +210,7 @@ void test13(unsigned len, unsigned index) {
return;
}
*q = '\0'; // $ deref=L213 // BAD
*q = '\0'; // $ deref=L206->L213 // BAD
}
bool unknown();
@@ -229,14 +229,14 @@ void test15(unsigned index) {
return;
}
int* newname = new int[size];
newname[index] = 0; // $ alloc=L231 deref=L232 // GOOD [FALSE POSITIVE]
newname[index] = 0; // GOOD
}
void test16(unsigned index) {
unsigned size = index + 13;
if(size >= index) {
int* newname = new int[size];
newname[index] = 0; // $ alloc=L238 deref=L239 // GOOD [FALSE POSITIVE]
newname[index] = 0; // GOOD
}
}
@@ -261,7 +261,7 @@ void test17(unsigned len)
int *end = xs + len; // $ alloc=L260
for (int *x = xs; x <= end; x++)
{
int i = *x; // $ deref=L264 // BAD
int i = *x; // $ deref=L261->L264 // BAD
}
}
@@ -271,7 +271,7 @@ void test18(unsigned len)
int *end = xs + len; // $ alloc=L270
for (int *x = xs; x <= end; x++)
{
*x = 0; // $ deref=L274 // BAD
*x = 0; // $ deref=L271->L274 // BAD
}
}
@@ -355,8 +355,8 @@ void test25(unsigned size) {
char *xs = new char[size];
char *end = xs + size; // $ alloc=L355
char *end_plus_one = end + 1;
int val1 = *end_plus_one; // $ deref=L358+1 // BAD
int val2 = *(end_plus_one + 1); // $ deref=L359+2 // BAD
int val1 = *end_plus_one; // $ deref=L356->L358+1 // BAD
int val2 = *(end_plus_one + 1); // $ deref=L356->L359+2 // BAD
}
void test26(unsigned size) {
@@ -381,7 +381,7 @@ void test27(unsigned size, bool b) {
end++;
}
int val = *end; // $ deref=L384+1 // BAD
int val = *end; // $ deref=L378->L384+1 // BAD
}
void test28(unsigned size) {
@@ -412,7 +412,7 @@ void test28_simple2(unsigned size) {
if (xs < end) {
xs++;
if (xs < end + 1) {
xs[0] = 0; // $ deref=L415 // BAD
xs[0] = 0; // $ deref=L411->L415 // BAD
}
}
}
@@ -423,7 +423,7 @@ void test28_simple3(unsigned size) {
if (xs < end) {
xs++;
if (xs - 1 < end) {
xs[0] = 0; // $ deref=L426 // BAD
xs[0] = 0; // $ deref=L422->L426 // BAD
}
}
}
@@ -435,7 +435,7 @@ void test28_simple4(unsigned size) {
end++;
xs++;
if (xs < end) {
xs[0] = 0; // $ deref=L438 // BAD
xs[0] = 0; // $ deref=L433->L438 // BAD
}
}
}
@@ -447,7 +447,7 @@ void test28_simple5(unsigned size) {
if (xs < end) {
xs++;
if (xs < end) {
xs[0] = 0; // $ deref=L450 // BAD
xs[0] = 0; // $ deref=L445->L450 // BAD
}
}
}
@@ -483,7 +483,7 @@ void test28_simple8(unsigned size) {
if (xs < end) {
xs++;
if (xs < end - 1) {
xs[0] = 0; // $ deref=L486+498 // BAD
xs[0] = 0; // $ deref=L481->L486+498 // BAD
}
}
}
@@ -698,12 +698,12 @@ void test34(unsigned size) {
p += 1;
}
if (p + 1 < end) {
int val = *p; // $ deref=L698->L700->L701 // GOOD [FALSE POSITIVE]
int val = *p; // GOOD
}
}
void deref(char* q) {
char x = *q; // $ deref=L714->L705->L706 // BAD
char x = *q; // $ MISSING: deref=L714->L705->L706 // BAD [NOT DETECTED]
}
void test35(size_t size, char* q)
@@ -730,7 +730,7 @@ void test36(unsigned size, unsigned n) {
int* p = new int[size + 2];
if(n < size + 1) {
int* end = p + (n + 2); // $ alloc=L730+2
*end = 0; // $ deref=L733 // BAD
*end = 0; // $ deref=L732->L733 // BAD
}
}
@@ -857,6 +857,6 @@ void test_regression(size_t size) {
int* chend = p + (size + 1); // $ alloc=L856+1
if(p <= chend) {
*p = 42; // $ deref=L860 // BAD
*p = 42; // $ deref=L857->L860 // BAD
}
}

View File

@@ -1,14 +1,7 @@
| test.cpp:12:6:12:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:11:6:11:8 | foo | foo |
| test.cpp:30:6:30:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:26:6:26:8 | foo | foo |
| test.cpp:46:6:46:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:42:6:42:8 | foo | foo |
| test.cpp:55:7:55:9 | foo | The variable $@ may not be initialized at this access. | test.cpp:50:6:50:8 | foo | foo |
| test.cpp:67:7:67:9 | foo | The variable $@ may not be initialized at this access. | test.cpp:61:6:61:8 | foo | foo |
| test.cpp:92:6:92:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:82:6:82:8 | foo | foo |
| test.cpp:113:6:113:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:111:6:111:8 | foo | foo |
| test.cpp:132:9:132:9 | j | The variable $@ may not be initialized at this access. | test.cpp:126:6:126:6 | j | j |
| test.cpp:219:3:219:3 | x | The variable $@ may not be initialized at this access. | test.cpp:218:7:218:7 | x | x |
| test.cpp:243:13:243:13 | i | The variable $@ may not be initialized at this access. | test.cpp:241:6:241:6 | i | i |
| test.cpp:329:9:329:11 | val | The variable $@ may not be initialized at this access. | test.cpp:321:6:321:8 | val | val |
| test.cpp:336:10:336:10 | a | The variable $@ may not be initialized at this access. | test.cpp:333:7:333:7 | a | a |
| test.cpp:369:10:369:10 | a | The variable $@ may not be initialized at this access. | test.cpp:358:7:358:7 | a | a |
| test.cpp:378:9:378:11 | val | The variable $@ may not be initialized at this access. | test.cpp:359:6:359:8 | val | val |

View File

@@ -27,7 +27,7 @@ void test4(bool b) {
if (b) {
foo = 1;
}
use(foo); // BAD
use(foo); // BAD [NOT DETECTED]
}
void test5() {
@@ -43,7 +43,7 @@ void test5(int count) {
for (int i = 0; i < count; i++) {
foo = i;
}
use(foo); // BAD
use(foo); // BAD [NOT DETECTED]
}
void test6(bool b) {
@@ -52,7 +52,7 @@ void test6(bool b) {
foo = 42;
}
if (b) {
use(foo); // GOOD (REPORTED, FP)
use(foo); // GOOD
}
}
@@ -64,7 +64,7 @@ void test7(bool b) {
set = true;
}
if (set) {
use(foo); // GOOD (REPORTED, FP)
use(foo); // GOOD
}
}
@@ -89,7 +89,7 @@ void test9(int count) {
if (!set) {
foo = 42;
}
use(foo); // GOOD (REPORTED, FP)
use(foo); // GOOD
}
void test10() {
@@ -129,7 +129,7 @@ int absWrong(int i) {
} else if (i < 0) {
j = -i;
}
return j; // wrong: j may not be initialized before use
return j; // wrong: j may not be initialized before use [NOT DETECTED]
}
// Example from qhelp
@@ -326,7 +326,7 @@ int test28() {
a = false;
c = false;
}
return val; // GOOD [FALSE POSITIVE]
return val; // GOOD
}
int test29() {
@@ -472,4 +472,64 @@ void test44() {
int y = 1;
void(x + y); // BAD
}
enum class State { StateA, StateB, StateC };
int exhaustive_switch(State s) {
int y;
switch(s) {
case State::StateA:
y = 1;
break;
case State::StateB:
y = 2;
break;
case State::StateC:
y = 3;
break;
}
return y; // GOOD (y is always initialized)
}
int exhaustive_switch_2(State s) {
int y;
switch(s) {
case State::StateA:
y = 1;
break;
default:
y = 2;
break;
}
return y; // GOOD (y is always initialized)
}
int non_exhaustive_switch(State s) {
int y;
switch(s) {
case State::StateA:
y = 1;
break;
case State::StateB:
y = 2;
break;
}
return y; // BAD [NOT DETECTED] (y is not initialized when s = StateC)
}
int non_exhaustive_switch_2(State s) {
int y;
switch(s) {
case State::StateA:
y = 1;
break;
case State::StateB:
y = 2;
break;
}
if(s != State::StateC) {
return y; // GOOD (y is not initialized when s = StateC, but if s = StateC we won't reach this point)
}
return 0;
}

View File

@@ -10,6 +10,7 @@ edges
| tests.cpp:131:14:131:35 | call to getenv indirection | tests.cpp:107:30:107:32 | msg indirection |
| tests.cpp:132:14:132:35 | call to getenv indirection | tests.cpp:114:30:114:32 | msg indirection |
| tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:122:30:122:32 | msg indirection |
| tests.cpp:139:17:139:22 | call to getenv indirection | tests.cpp:141:15:141:20 | secret indirection |
| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:18:29:18:31 | pwd indirection |
| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:19:26:19:28 | pwd indirection |
nodes
@@ -37,6 +38,8 @@ nodes
| tests.cpp:132:14:132:35 | call to getenv indirection | semmle.label | call to getenv indirection |
| tests.cpp:133:14:133:35 | call to getenv indirection | semmle.label | call to getenv indirection |
| tests.cpp:133:14:133:35 | call to getenv indirection | semmle.label | call to getenv indirection |
| tests.cpp:139:17:139:22 | call to getenv indirection | semmle.label | call to getenv indirection |
| tests.cpp:141:15:141:20 | secret indirection | semmle.label | secret indirection |
| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | semmle.label | call to getpwnam indirection |
| tests_passwd.cpp:18:29:18:31 | pwd indirection | semmle.label | pwd indirection |
| tests_passwd.cpp:19:26:19:28 | pwd indirection | semmle.label | pwd indirection |
@@ -56,5 +59,6 @@ subpaths
| tests.cpp:119:7:119:12 | buffer indirection | tests.cpp:132:14:132:35 | call to getenv indirection | tests.cpp:119:7:119:12 | buffer indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:132:14:132:35 | call to getenv indirection | call to getenv indirection |
| tests.cpp:124:15:124:17 | msg indirection | tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:124:15:124:17 | msg indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:35 | call to getenv indirection | call to getenv indirection |
| tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:133:14:133:35 | call to getenv indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:35 | call to getenv indirection | call to getenv indirection |
| tests.cpp:141:15:141:20 | secret indirection | tests.cpp:139:17:139:22 | call to getenv indirection | tests.cpp:141:15:141:20 | secret indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:139:17:139:22 | call to getenv indirection | call to getenv indirection |
| tests_passwd.cpp:18:29:18:31 | pwd indirection | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:18:29:18:31 | pwd indirection | This operation potentially exposes sensitive system data from $@. | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | call to getpwnam indirection |
| tests_passwd.cpp:19:26:19:28 | pwd indirection | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:19:26:19:28 | pwd indirection | This operation potentially exposes sensitive system data from $@. | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | call to getpwnam indirection |

View File

@@ -132,3 +132,13 @@ void test5()
myOutputFn4(getenv("SECRET_TOKEN")); // BAD: outputs the SECRET_TOKEN environment variable
myOutputFn5(getenv("SECRET_TOKEN")); // BAD: outputs the SECRET_TOKEN environment variable
}
void RtlZeroMemory(void* dst, size_t len);
void test_clear_memory(char *username) {
char* secret = getenv("SECRET_TOKEN");
printf("%s", secret); // BAD
RtlZeroMemory(secret, 1024);
printf("%s", secret); // GOOD
}

View File

@@ -22,31 +22,19 @@ edges
| tests5.cpp:88:2:88:2 | p indirection | tests5.cpp:89:2:89:2 | p indirection |
| tests.cpp:15:23:15:43 | call to XercesDOMParser | tests.cpp:17:2:17:2 | p indirection |
| tests.cpp:28:23:28:43 | call to XercesDOMParser | tests.cpp:31:2:31:2 | p indirection |
| tests.cpp:35:23:35:43 | call to XercesDOMParser | tests.cpp:37:2:37:2 | (AbstractDOMParser *)... indirection |
| tests.cpp:35:23:35:43 | call to XercesDOMParser | tests.cpp:37:2:37:2 | p indirection |
| tests.cpp:37:2:37:2 | (AbstractDOMParser *)... indirection | tests.cpp:37:2:37:2 | p indirection |
| tests.cpp:37:2:37:2 | p indirection | tests.cpp:37:2:37:2 | p indirection |
| tests.cpp:37:2:37:2 | p indirection | tests.cpp:38:2:38:2 | (AbstractDOMParser *)... indirection |
| tests.cpp:37:2:37:2 | p indirection | tests.cpp:38:2:38:2 | p indirection |
| tests.cpp:38:2:38:2 | (AbstractDOMParser *)... indirection | tests.cpp:38:2:38:2 | p indirection |
| tests.cpp:38:2:38:2 | p indirection | tests.cpp:38:2:38:2 | p indirection |
| tests.cpp:38:2:38:2 | p indirection | tests.cpp:39:2:39:2 | p indirection |
| tests.cpp:51:23:51:43 | call to XercesDOMParser | tests.cpp:53:2:53:2 | (AbstractDOMParser *)... indirection |
| tests.cpp:51:23:51:43 | call to XercesDOMParser | tests.cpp:53:2:53:2 | p indirection |
| tests.cpp:53:2:53:2 | (AbstractDOMParser *)... indirection | tests.cpp:53:2:53:2 | p indirection |
| tests.cpp:53:2:53:2 | p indirection | tests.cpp:53:2:53:2 | p indirection |
| tests.cpp:53:2:53:2 | p indirection | tests.cpp:55:2:55:2 | (AbstractDOMParser *)... indirection |
| tests.cpp:53:2:53:2 | p indirection | tests.cpp:55:2:55:2 | p indirection |
| tests.cpp:55:2:55:2 | (AbstractDOMParser *)... indirection | tests.cpp:55:2:55:2 | p indirection |
| tests.cpp:55:2:55:2 | p indirection | tests.cpp:55:2:55:2 | p indirection |
| tests.cpp:55:2:55:2 | p indirection | tests.cpp:56:2:56:2 | p indirection |
| tests.cpp:55:2:55:2 | p indirection | tests.cpp:57:2:57:2 | (AbstractDOMParser *)... indirection |
| tests.cpp:55:2:55:2 | p indirection | tests.cpp:57:2:57:2 | p indirection |
| tests.cpp:57:2:57:2 | (AbstractDOMParser *)... indirection | tests.cpp:57:2:57:2 | p indirection |
| tests.cpp:57:2:57:2 | p indirection | tests.cpp:57:2:57:2 | p indirection |
| tests.cpp:57:2:57:2 | p indirection | tests.cpp:59:2:59:2 | (AbstractDOMParser *)... indirection |
| tests.cpp:57:2:57:2 | p indirection | tests.cpp:59:2:59:2 | p indirection |
| tests.cpp:59:2:59:2 | (AbstractDOMParser *)... indirection | tests.cpp:59:2:59:2 | p indirection |
| tests.cpp:59:2:59:2 | p indirection | tests.cpp:59:2:59:2 | p indirection |
| tests.cpp:59:2:59:2 | p indirection | tests.cpp:60:2:60:2 | p indirection |
| tests.cpp:66:23:66:43 | call to XercesDOMParser | tests.cpp:69:2:69:2 | p indirection |
@@ -104,25 +92,19 @@ nodes
| tests.cpp:28:23:28:43 | call to XercesDOMParser | semmle.label | call to XercesDOMParser |
| tests.cpp:31:2:31:2 | p indirection | semmle.label | p indirection |
| tests.cpp:35:23:35:43 | call to XercesDOMParser | semmle.label | call to XercesDOMParser |
| tests.cpp:37:2:37:2 | (AbstractDOMParser *)... indirection | semmle.label | (AbstractDOMParser *)... indirection |
| tests.cpp:37:2:37:2 | p indirection | semmle.label | p indirection |
| tests.cpp:37:2:37:2 | p indirection | semmle.label | p indirection |
| tests.cpp:38:2:38:2 | (AbstractDOMParser *)... indirection | semmle.label | (AbstractDOMParser *)... indirection |
| tests.cpp:38:2:38:2 | p indirection | semmle.label | p indirection |
| tests.cpp:38:2:38:2 | p indirection | semmle.label | p indirection |
| tests.cpp:39:2:39:2 | p indirection | semmle.label | p indirection |
| tests.cpp:51:23:51:43 | call to XercesDOMParser | semmle.label | call to XercesDOMParser |
| tests.cpp:53:2:53:2 | (AbstractDOMParser *)... indirection | semmle.label | (AbstractDOMParser *)... indirection |
| tests.cpp:53:2:53:2 | p indirection | semmle.label | p indirection |
| tests.cpp:53:2:53:2 | p indirection | semmle.label | p indirection |
| tests.cpp:55:2:55:2 | (AbstractDOMParser *)... indirection | semmle.label | (AbstractDOMParser *)... indirection |
| tests.cpp:55:2:55:2 | p indirection | semmle.label | p indirection |
| tests.cpp:55:2:55:2 | p indirection | semmle.label | p indirection |
| tests.cpp:56:2:56:2 | p indirection | semmle.label | p indirection |
| tests.cpp:57:2:57:2 | (AbstractDOMParser *)... indirection | semmle.label | (AbstractDOMParser *)... indirection |
| tests.cpp:57:2:57:2 | p indirection | semmle.label | p indirection |
| tests.cpp:57:2:57:2 | p indirection | semmle.label | p indirection |
| tests.cpp:59:2:59:2 | (AbstractDOMParser *)... indirection | semmle.label | (AbstractDOMParser *)... indirection |
| tests.cpp:59:2:59:2 | p indirection | semmle.label | p indirection |
| tests.cpp:59:2:59:2 | p indirection | semmle.label | p indirection |
| tests.cpp:60:2:60:2 | p indirection | semmle.label | p indirection |

View File

@@ -159,9 +159,9 @@ namespace Semmle.Autobuild.CSharp.Tests
bool IBuildActions.IsMacOs() => IsMacOs;
public bool IsArm { get; set; }
public bool IsRunningOnAppleSilicon { get; set; }
bool IBuildActions.IsArm() => IsArm;
bool IBuildActions.IsRunningOnAppleSilicon() => IsRunningOnAppleSilicon;
public string PathCombine(params string[] parts)
{

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Xml;
using Semmle.Util;
@@ -119,10 +120,10 @@ namespace Semmle.Autobuild.Shared
bool IsMacOs();
/// <summary>
/// Gets a value indicating whether we are running on arm.
/// Gets a value indicating whether we are running on Apple Silicon.
/// </summary>
/// <returns>True if we are running on arm.</returns>
bool IsArm();
/// <returns>True if we are running on Apple Silicon.</returns>
bool IsRunningOnAppleSilicon();
/// <summary>
/// Combine path segments, Path.Combine().
@@ -240,9 +241,25 @@ namespace Semmle.Autobuild.Shared
bool IBuildActions.IsMacOs() => RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
bool IBuildActions.IsArm() =>
RuntimeInformation.ProcessArchitecture == Architecture.Arm64 ||
RuntimeInformation.ProcessArchitecture == Architecture.Arm;
bool IBuildActions.IsRunningOnAppleSilicon()
{
var thisBuildActions = (IBuildActions)this;
if (!thisBuildActions.IsMacOs())
{
return false;
}
try
{
thisBuildActions.RunProcess("sysctl", "machdep.cpu.brand_string", workingDirectory: null, env: null, out var stdOut);
return stdOut?.Any(s => s?.ToLowerInvariant().Contains("apple") == true) ?? false;
}
catch (Exception)
{
return false;
}
}
string IBuildActions.PathCombine(params string[] parts) => Path.Combine(parts);

View File

@@ -15,14 +15,12 @@ namespace Semmle.Autobuild.Shared
/// <returns></returns>
public static CommandBuilder MsBuildCommand(this CommandBuilder cmdBuilder, IAutobuilder<AutobuildOptionsShared> builder)
{
var isArmMac = builder.Actions.IsMacOs() && builder.Actions.IsArm();
// mono doesn't ship with `msbuild` on Arm-based Macs, but we can fall back to
// msbuild that ships with `dotnet` which can be invoked with `dotnet msbuild`
// perhaps we should do this on all platforms?
return isArmMac ?
cmdBuilder.RunCommand("dotnet").Argument("msbuild") :
cmdBuilder.RunCommand("msbuild");
return builder.Actions.IsRunningOnAppleSilicon()
? cmdBuilder.RunCommand("dotnet").Argument("msbuild")
: cmdBuilder.RunCommand("msbuild");
}
}
@@ -84,7 +82,12 @@ namespace Semmle.Autobuild.Shared
Argument("/t:restore").
QuoteArgument(projectOrSolution.FullPath);
if (nugetDownloaded)
if (builder.Actions.IsRunningOnAppleSilicon())
{
// On Apple Silicon, only try package restore with `dotnet msbuild /t:restore`
ret &= BuildScript.Try(msbuildRestoreCommand.Script);
}
else if (nugetDownloaded)
{
ret &= BuildScript.Try(nugetRestore | msbuildRestoreCommand.Script);
}

View File

@@ -1,28 +1,33 @@
package,sink,source,summary,sink:code-injection,sink:encryption-decryptor,sink:encryption-encryptor,sink:encryption-keyprop,sink:encryption-symmetrickey,sink:file-content-store,sink:html-injection,sink:js-injection,sink:sql-injection,source:file,source:file-write,source:local,source:remote,summary:taint,summary:value
Dapper,55,,,,,,,,,,,55,,,,,,
ILCompiler,,,80,,,,,,,,,,,,,,80,
Internal.IL,,,68,,,,,,,,,,,,,,66,2
Internal.Pgo,,,9,,,,,,,,,,,,,,8,1
Internal.TypeSystem,,,352,,,,,,,,,,,,,,316,36
JsonToItemsTaskFactory,,,7,,,,,,,,,,,,,,7,
Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,,28,,,,,,
Microsoft.CSharp,,,24,,,,,,,,,,,,,,24,
Microsoft.Diagnostics.Tools.Pgo,,,12,,,,,,,,,,,,,,12,
Microsoft.EntityFrameworkCore,6,,12,,,,,,,,,6,,,,,,12
Microsoft.Extensions.Caching.Distributed,,,15,,,,,,,,,,,,,,15,
Microsoft.Extensions.Caching.Memory,,,46,,,,,,,,,,,,,,45,1
Microsoft.Extensions.Configuration,,,83,,,,,,,,,,,,,,80,3
Microsoft.Extensions.DependencyInjection,,,62,,,,,,,,,,,,,,62,
Microsoft.Extensions.Caching.Memory,,,38,,,,,,,,,,,,,,37,1
Microsoft.Extensions.Configuration,,,79,,,,,,,,,,,,,,76,3
Microsoft.Extensions.DependencyInjection,,,60,,,,,,,,,,,,,,60,
Microsoft.Extensions.DependencyModel,,,12,,,,,,,,,,,,,,12,
Microsoft.Extensions.FileProviders,,,16,,,,,,,,,,,,,,16,
Microsoft.Extensions.FileSystemGlobbing,,,15,,,,,,,,,,,,,,13,2
Microsoft.Extensions.Hosting,,,17,,,,,,,,,,,,,,16,1
Microsoft.Extensions.FileProviders,,,17,,,,,,,,,,,,,,17,
Microsoft.Extensions.FileSystemGlobbing,,,16,,,,,,,,,,,,,,14,2
Microsoft.Extensions.Hosting,,,20,,,,,,,,,,,,,,19,1
Microsoft.Extensions.Http,,,10,,,,,,,,,,,,,,10,
Microsoft.Extensions.Logging,,,37,,,,,,,,,,,,,,37,
Microsoft.Extensions.Logging,,,39,,,,,,,,,,,,,,39,
Microsoft.Extensions.Options,,,8,,,,,,,,,,,,,,8,
Microsoft.Extensions.Primitives,,,63,,,,,,,,,,,,,,63,
Microsoft.Interop,,,27,,,,,,,,,,,,,,27,
Microsoft.Interop,,,60,,,,,,,,,,,,,,60,
Microsoft.NET.Build.Tasks,,,1,,,,,,,,,,,,,,1,
Microsoft.NETCore.Platforms.BuildTasks,,,4,,,,,,,,,,,,,,4,
Microsoft.VisualBasic,,,10,,,,,,,,,,,,,,5,5
Microsoft.Win32,,,8,,,,,,,,,,,,,,8,
Microsoft.Win32.SafeHandles,,,4,,,,,,,,,,,,,,4,
MySql.Data.MySqlClient,48,,,,,,,,,,,48,,,,,,
Newtonsoft.Json,,,91,,,,,,,,,,,,,,73,18
ServiceStack,194,,7,27,,,,,75,,,92,,,,,7,
System,65,25,12149,,8,8,9,,,4,3,33,1,17,3,4,10163,1986
System,67,25,11891,,8,8,9,,,4,5,33,1,17,3,4,9906,1985
Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,,,
1 package sink source summary sink:code-injection sink:encryption-decryptor sink:encryption-encryptor sink:encryption-keyprop sink:encryption-symmetrickey sink:file-content-store sink:html-injection sink:js-injection sink:sql-injection source:file source:file-write source:local source:remote summary:taint summary:value
2 Dapper 55 55
3 ILCompiler 80 80
4 Internal.IL 68 66 2
5 Internal.Pgo 9 8 1
6 Internal.TypeSystem 352 316 36
7 JsonToItemsTaskFactory 7 7
8 Microsoft.ApplicationBlocks.Data 28 28
9 Microsoft.CSharp 24 24
10 Microsoft.Diagnostics.Tools.Pgo 12 12
11 Microsoft.EntityFrameworkCore 6 12 6 12
12 Microsoft.Extensions.Caching.Distributed 15 15
13 Microsoft.Extensions.Caching.Memory 46 38 45 37 1
14 Microsoft.Extensions.Configuration 83 79 80 76 3
15 Microsoft.Extensions.DependencyInjection 62 60 62 60
16 Microsoft.Extensions.DependencyModel 12 12
17 Microsoft.Extensions.FileProviders 16 17 16 17
18 Microsoft.Extensions.FileSystemGlobbing 15 16 13 14 2
19 Microsoft.Extensions.Hosting 17 20 16 19 1
20 Microsoft.Extensions.Http 10 10
21 Microsoft.Extensions.Logging 37 39 37 39
22 Microsoft.Extensions.Options 8 8
23 Microsoft.Extensions.Primitives 63 63
24 Microsoft.Interop 27 60 27 60
25 Microsoft.NET.Build.Tasks 1 1
26 Microsoft.NETCore.Platforms.BuildTasks 4 4
27 Microsoft.VisualBasic 10 5 5
28 Microsoft.Win32 Microsoft.Win32.SafeHandles 8 4 8 4
29 MySql.Data.MySqlClient 48 48
30 Newtonsoft.Json 91 73 18
31 ServiceStack 194 7 27 75 92 7
32 System 65 67 25 12149 11891 8 8 9 4 3 5 33 1 17 3 4 10163 9906 1986 1985
33 Windows.Security.Cryptography.Core 1 1

View File

@@ -8,7 +8,7 @@ C# framework & library support
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting`
`ServiceStack <https://servicestack.net/>`_,"``ServiceStack.*``, ``ServiceStack``",,7,194,
System,"``System.*``, ``System``",25,12149,65,7
Others,"``Dapper``, ``JsonToItemsTaskFactory``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NETCore.Platforms.BuildTasks``, ``Microsoft.VisualBasic``, ``Microsoft.Win32``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``Windows.Security.Cryptography.Core``",,568,138,
Totals,,25,12724,397,7
System,"``System.*``, ``System``",25,11891,67,9
Others,"``Dapper``, ``ILCompiler``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NETCore.Platforms.BuildTasks``, ``Microsoft.VisualBasic``, ``Microsoft.Win32.SafeHandles``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``Windows.Security.Cryptography.Core``",,1111,138,
Totals,,25,13009,399,9

View File

@@ -27,12 +27,18 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
if (File.Exists(path))
{
pendingDllsToIndex.Enqueue(path);
continue;
}
else
if (Directory.Exists(path))
{
progressMonitor.FindingFiles(path);
AddReferenceDirectory(path);
}
else
{
progressMonitor.LogInfo("AssemblyCache: Path not found: " + path);
}
}
IndexReferences();
}

View File

@@ -0,0 +1,164 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json.Linq;
using Semmle.Util;
namespace Semmle.Extraction.CSharp.DependencyFetching
{
/// <summary>
/// Class for parsing project.assets.json files.
/// </summary>
internal class Assets
{
private readonly ProgressMonitor progressMonitor;
private static readonly string[] netFrameworks = new[] {
"microsoft.aspnetcore.app.ref",
"microsoft.netcore.app.ref",
"microsoft.netframework.referenceassemblies",
"microsoft.windowsdesktop.app.ref",
"netstandard.library.ref"
};
internal Assets(ProgressMonitor progressMonitor)
{
this.progressMonitor = progressMonitor;
}
/// <summary>
/// Class needed for deserializing parts of an assets file.
/// It holds information about a reference.
///
/// Type carries the type of the reference.
/// We are only interested in package references.
///
/// Compile holds information about the files needed for compilation.
/// However, if it is a .NET framework reference we assume that all files in the
/// package are needed for compilation.
/// </summary>
private record class ReferenceInfo(string? Type, Dictionary<string, object>? Compile);
/// <summary>
/// Add the package dependencies from the assets file to dependencies.
///
/// Parse a part of the JSon assets file and add the paths
/// to the dependencies required for compilation (and collect
/// information about used packages).
///
/// Example:
/// {
/// "Castle.Core/4.4.1": {
/// "type": "package",
/// "compile": {
/// "lib/netstandard1.5/Castle.Core.dll": {
/// "related": ".xml"
/// }
/// }
/// },
/// "Json.Net/1.0.33": {
/// "type": "package",
/// "compile": {
/// "lib/netstandard2.0/Json.Net.dll": {}
/// },
/// "runtime": {
/// "lib/netstandard2.0/Json.Net.dll": {}
/// }
/// }
/// }
///
/// Returns dependencies
/// RequiredPaths = {
/// "castle.core/4.4.1/lib/netstandard1.5/Castle.Core.dll",
/// "json.net/1.0.33/lib/netstandard2.0/Json.Net.dll"
/// }
/// UsedPackages = {
/// "castle.core",
/// "json.net"
/// }
/// </summary>
private DependencyContainer AddPackageDependencies(JObject json, DependencyContainer dependencies)
{
// If there are more than one framework we need to pick just one.
// To ensure stability we pick one based on the lexicographic order of
// the framework names.
var references = json
.GetProperty("targets")?
.Properties()?
.MaxBy(p => p.Name)?
.Value
.ToObject<Dictionary<string, ReferenceInfo>>();
if (references is null)
{
progressMonitor.LogDebug("No references found in the targets section in the assets file.");
return dependencies;
}
// Find all the compile dependencies for each reference and
// create the relative path to the dependency.
references
.ForEach(r =>
{
var info = r.Value;
var name = r.Key.ToLowerInvariant();
if (info.Type != "package")
{
return;
}
// If this is a .NET framework reference then include everything.
if (netFrameworks.Any(framework => name.StartsWith(framework)))
{
dependencies.Add(name);
}
else
{
info.Compile?
.ForEach(r => dependencies.Add(name, r.Key));
}
});
return dependencies;
}
/// <summary>
/// Parse `json` as project.assets.json content and add relative paths to the dependencies
/// (together with used package information) required for compilation.
/// </summary>
/// <returns>True if parsing succeeds, otherwise false.</returns>
public bool TryParse(string json, DependencyContainer dependencies)
{
try
{
var obj = JObject.Parse(json);
AddPackageDependencies(obj, dependencies);
return true;
}
catch (Exception e)
{
progressMonitor.LogDebug($"Failed to parse assets file (unexpected error): {e.Message}");
return false;
}
}
public static DependencyContainer GetCompilationDependencies(ProgressMonitor progressMonitor, IEnumerable<string> assets)
{
var parser = new Assets(progressMonitor);
var dependencies = new DependencyContainer();
assets.ForEach(asset =>
{
var json = File.ReadAllText(asset);
parser.TryParse(json, dependencies);
});
return dependencies;
}
}
internal static class JsonExtensions
{
internal static JObject? GetProperty(this JObject json, string property) =>
json[property] as JObject;
}
}

View File

@@ -0,0 +1,69 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Semmle.Extraction.CSharp.DependencyFetching
{
/// <summary>
/// Container class for dependencies found in the assets file.
/// </summary>
internal class DependencyContainer
{
private readonly List<string> requiredPaths = new();
private readonly HashSet<string> usedPackages = new();
/// <summary>
/// In most cases paths in asset files point to dll's or the empty _._ file, which
/// is sometimes there to avoid the directory being empty.
/// That is, if the path specifically adds a .dll we use that, otherwise we as a fallback
/// add the entire directory (which should be fine in case of _._ as well).
/// </summary>
private static string ParseFilePath(string path)
{
if (path.EndsWith(".dll"))
{
return path;
}
return Path.GetDirectoryName(path) ?? path;
}
private static string GetPackageName(string package) =>
package
.Split(Path.DirectorySeparatorChar)
.First();
/// <summary>
/// Paths to dependencies required for compilation.
/// </summary>
public IEnumerable<string> RequiredPaths => requiredPaths;
/// <summary>
/// Packages that are used as a part of the required dependencies.
/// </summary>
public HashSet<string> UsedPackages => usedPackages;
/// <summary>
/// Add a dependency inside a package.
/// </summary>
public void Add(string package, string dependency)
{
var p = package.Replace('/', Path.DirectorySeparatorChar);
var d = dependency.Replace('/', Path.DirectorySeparatorChar);
var path = Path.Combine(p, ParseFilePath(d));
requiredPaths.Add(path);
usedPackages.Add(GetPackageName(p));
}
/// <summary>
/// Add a dependency to an entire package
/// </summary>
public void Add(string package)
{
var p = package.Replace('/', Path.DirectorySeparatorChar);
requiredPaths.Add(p);
usedPackages.Add(GetPackageName(p));
}
}
}

View File

@@ -31,9 +31,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private readonly IDotNet dotnet;
private readonly FileContent fileContent;
private readonly TemporaryDirectory packageDirectory;
private readonly TemporaryDirectory legacyPackageDirectory;
private readonly TemporaryDirectory missingPackageDirectory;
private readonly TemporaryDirectory tempWorkingDirectory;
private readonly bool cleanupTempWorkingDirectory;
private readonly Lazy<Runtime> runtimeLazy;
private Runtime Runtime => runtimeLazy.Value;
/// <summary>
/// Performs C# dependency fetching.
/// </summary>
@@ -48,11 +53,15 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
this.sourceDir = new DirectoryInfo(srcDir);
packageDirectory = new TemporaryDirectory(ComputeTempDirectory(sourceDir.FullName));
legacyPackageDirectory = new TemporaryDirectory(ComputeTempDirectory(sourceDir.FullName, "legacypackages"));
missingPackageDirectory = new TemporaryDirectory(ComputeTempDirectory(sourceDir.FullName, "missingpackages"));
tempWorkingDirectory = new TemporaryDirectory(FileUtils.GetTemporaryWorkingDirectory(out cleanupTempWorkingDirectory));
try
{
this.dotnet = DotNet.Make(options, progressMonitor, tempWorkingDirectory);
runtimeLazy = new Lazy<Runtime>(() => new Runtime(dotnet));
}
catch
{
@@ -74,50 +83,61 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var solutions = options.SolutionFile is not null
? new[] { options.SolutionFile }
: allNonBinaryFiles.SelectFileNamesByExtension(".sln");
var dllDirNames = options.DllDirs.Count == 0
? allFiles.SelectFileNamesByExtension(".dll").ToList()
: options.DllDirs.Select(Path.GetFullPath).ToList();
var dllPaths = options.DllDirs.Count == 0
? allFiles.SelectFileNamesByExtension(".dll").ToHashSet()
: options.DllDirs.Select(Path.GetFullPath).ToHashSet();
if (options.UseNuGet)
{
dllDirNames.Add(packageDirectory.DirInfo.FullName);
try
{
var nuget = new NugetPackages(sourceDir.FullName, packageDirectory, progressMonitor);
var nuget = new NugetPackages(sourceDir.FullName, legacyPackageDirectory, progressMonitor);
nuget.InstallPackages();
var nugetPackageDlls = legacyPackageDirectory.DirInfo.GetFiles("*.dll", new EnumerationOptions { RecurseSubdirectories = true });
var nugetPackageDllPaths = nugetPackageDlls.Select(f => f.FullName).ToHashSet();
var excludedPaths = nugetPackageDllPaths
.Where(path => IsPathInSubfolder(path, legacyPackageDirectory.DirInfo.FullName, "tools"));
foreach (var excludedPath in excludedPaths)
{
progressMonitor.LogInfo($"Excluded Nuget DLL: {excludedPath}");
}
nugetPackageDllPaths.ExceptWith(excludedPaths);
dllPaths.UnionWith(nugetPackageDllPaths);
}
catch (FileNotFoundException)
{
progressMonitor.MissingNuGet();
}
var restoredProjects = RestoreSolutions(solutions);
var restoredProjects = RestoreSolutions(solutions, out var assets1);
var projects = allProjects.Except(restoredProjects);
RestoreProjects(projects);
DownloadMissingPackages(allNonBinaryFiles);
}
RestoreProjects(projects, out var assets2);
var existsNetCoreRefNugetPackage = false;
var existsNetFrameworkRefNugetPackage = false;
var dependencies = Assets.GetCompilationDependencies(progressMonitor, assets1.Union(assets2));
var paths = dependencies
.RequiredPaths
.Select(d => Path.Combine(packageDirectory.DirInfo.FullName, d))
.ToList();
dllPaths.UnionWith(paths);
LogAllUnusedPackages(dependencies);
DownloadMissingPackages(allNonBinaryFiles, dllPaths);
}
// Find DLLs in the .Net / Asp.Net Framework
// This block needs to come after the nuget restore, because the nuget restore might fetch the .NET Core/Framework reference assemblies.
if (options.ScanNetFrameworkDlls)
{
existsNetCoreRefNugetPackage = IsNugetPackageAvailable("microsoft.netcore.app.ref");
existsNetFrameworkRefNugetPackage = IsNugetPackageAvailable("microsoft.netframework.referenceassemblies");
if (existsNetCoreRefNugetPackage || existsNetFrameworkRefNugetPackage)
{
progressMonitor.LogInfo("Found .NET Core/Framework DLLs in NuGet packages. Not adding installation directory.");
}
else
{
AddNetFrameworkDlls(dllDirNames);
}
AddNetFrameworkDlls(dllPaths);
AddAspNetCoreFrameworkDlls(dllPaths);
AddMicrosoftWindowsDesktopDlls(dllPaths);
}
assemblyCache = new AssemblyCache(dllDirNames, progressMonitor);
assemblyCache = new AssemblyCache(dllPaths, progressMonitor);
AnalyseSolutions(solutions);
foreach (var filename in assemblyCache.AllAssemblies.Select(a => a.Filename))
@@ -125,7 +145,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
UseReference(filename);
}
RemoveUnnecessaryNugetPackages(existsNetCoreRefNugetPackage, existsNetFrameworkRefNugetPackage);
RemoveNugetAnalyzerReferences();
ResolveConflicts();
// Output the findings
@@ -160,27 +180,12 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
DateTime.Now - startTime);
}
private void RemoveUnnecessaryNugetPackages(bool existsNetCoreRefNugetPackage, bool existsNetFrameworkRefNugetPackage)
private static bool IsPathInSubfolder(string path, string rootFolder, string subFolder)
{
RemoveNugetAnalyzerReferences();
RemoveRuntimeNugetPackageReferences();
if (fileContent.IsNewProjectStructureUsed
&& !fileContent.UseAspNetCoreDlls)
{
// This might have been restored by the CLI even though the project isn't an asp.net core one.
RemoveNugetPackageReference("microsoft.aspnetcore.app.ref");
}
if (existsNetCoreRefNugetPackage && existsNetFrameworkRefNugetPackage)
{
// Multiple packages are available, we keep only one:
RemoveNugetPackageReference("microsoft.netframework.referenceassemblies.");
}
// TODO: There could be multiple `microsoft.netframework.referenceassemblies` packages,
// we could keep the newest one, but this is covered by the conflict resolution logic
// (if the file names match)
return path.IndexOf(
$"{Path.DirectorySeparatorChar}{subFolder}{Path.DirectorySeparatorChar}",
rootFolder.Length,
StringComparison.InvariantCultureIgnoreCase) >= 0;
}
private void RemoveNugetAnalyzerReferences()
@@ -222,58 +227,58 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
}
}
private void AddNetFrameworkDlls(List<string> dllDirNames)
private void AddNetFrameworkDlls(ISet<string> dllPaths)
{
var runtime = new Runtime(dotnet);
// Multiple dotnet framework packages could be present.
// The order of the packages is important, we're adding the first one that is present in the nuget cache.
var packagesInPrioOrder = new string[]
{
"microsoft.netcore.app.ref", // net7.0, ... net5.0, netcoreapp3.1, netcoreapp3.0
"microsoft.netframework.referenceassemblies.", // net48, ..., net20
"netstandard.library.ref", // netstandard2.1
"netstandard.library" // netstandard2.0
};
var frameworkPath = packagesInPrioOrder
.Select((s, index) => (Index: index, Path: GetPackageDirectory(s)))
.FirstOrDefault(pair => pair.Path is not null);
if (frameworkPath.Path is not null)
{
dllPaths.Add(frameworkPath.Path);
progressMonitor.LogInfo($"Found .NET Core/Framework DLLs in NuGet packages at {frameworkPath.Path}. Not adding installation directory.");
for (var i = frameworkPath.Index + 1; i < packagesInPrioOrder.Length; i++)
{
RemoveNugetPackageReference(packagesInPrioOrder[i], dllPaths);
}
return;
}
string? runtimeLocation = null;
if (options.UseSelfContainedDotnet)
{
runtimeLocation = runtime.ExecutingRuntime;
runtimeLocation = Runtime.ExecutingRuntime;
}
else if (fileContent.IsNewProjectStructureUsed)
{
runtimeLocation = runtime.NetCoreRuntime;
runtimeLocation = Runtime.NetCoreRuntime;
}
else if (fileContent.IsLegacyProjectStructureUsed)
{
runtimeLocation = runtime.DesktopRuntime;
runtimeLocation = Runtime.DesktopRuntime;
}
runtimeLocation ??= runtime.ExecutingRuntime;
runtimeLocation ??= Runtime.ExecutingRuntime;
progressMonitor.LogInfo($".NET runtime location selected: {runtimeLocation}");
dllDirNames.Add(runtimeLocation);
if (fileContent.IsNewProjectStructureUsed
&& fileContent.UseAspNetCoreDlls
&& runtime.AspNetCoreRuntime is string aspRuntime)
{
progressMonitor.LogInfo($"ASP.NET runtime location selected: {aspRuntime}");
dllDirNames.Add(aspRuntime);
}
dllPaths.Add(runtimeLocation);
}
private void RemoveRuntimeNugetPackageReferences()
{
var runtimePackagePrefixes = new[]
{
"microsoft.netcore.app.runtime",
"microsoft.aspnetcore.app.runtime",
"microsoft.windowsdesktop.app.runtime",
// legacy runtime packages:
"runtime.linux-x64.microsoft.netcore.app",
"runtime.osx-x64.microsoft.netcore.app",
"runtime.win-x64.microsoft.netcore.app",
// Internal implementation packages not meant for direct consumption:
"runtime."
};
RemoveNugetPackageReference(runtimePackagePrefixes);
}
private void RemoveNugetPackageReference(params string[] packagePrefixes)
private void RemoveNugetPackageReference(string packagePrefix, ISet<string> dllPaths)
{
if (!options.UseNuGet)
{
@@ -286,32 +291,74 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
return;
}
var packagePathPrefixes = packagePrefixes.Select(p => Path.Combine(packageFolder, p.ToLowerInvariant()));
foreach (var filename in usedReferences.Keys)
var packagePathPrefix = Path.Combine(packageFolder, packagePrefix.ToLowerInvariant());
var toRemove = dllPaths.Where(s => s.ToLowerInvariant().StartsWith(packagePathPrefix));
foreach (var path in toRemove)
{
var lowerFilename = filename.ToLowerInvariant();
if (packagePathPrefixes.Any(prefix => lowerFilename.StartsWith(prefix)))
{
usedReferences.Remove(filename);
progressMonitor.RemovedReference(filename);
}
dllPaths.Remove(path);
progressMonitor.RemovedReference(path);
}
}
private bool IsNugetPackageAvailable(string packagePrefix)
private void AddAspNetCoreFrameworkDlls(ISet<string> dllPaths)
{
if (!fileContent.IsNewProjectStructureUsed || !fileContent.UseAspNetCoreDlls)
{
return;
}
// First try to find ASP.NET Core assemblies in the NuGet packages
if (GetPackageDirectory("microsoft.aspnetcore.app.ref") is string aspNetCorePackage)
{
progressMonitor.LogInfo($"Found ASP.NET Core in NuGet packages. Not adding installation directory.");
dllPaths.Add(aspNetCorePackage);
}
else if (Runtime.AspNetCoreRuntime is string aspNetCoreRuntime)
{
progressMonitor.LogInfo($"ASP.NET runtime location selected: {aspNetCoreRuntime}");
dllPaths.Add(aspNetCoreRuntime);
}
}
private void AddMicrosoftWindowsDesktopDlls(ISet<string> dllPaths)
{
if (GetPackageDirectory("microsoft.windowsdesktop.app.ref") is string windowsDesktopApp)
{
progressMonitor.LogInfo($"Found Windows Desktop App in NuGet packages.");
dllPaths.Add(windowsDesktopApp);
}
}
private string? GetPackageDirectory(string packagePrefix)
{
if (!options.UseNuGet)
{
return false;
return null;
}
return new DirectoryInfo(packageDirectory.DirInfo.FullName)
.EnumerateDirectories(packagePrefix + "*", new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive, RecurseSubdirectories = false })
.Any();
.FirstOrDefault()?
.FullName;
}
private IEnumerable<string> GetAllPackageDirectories()
{
if (!options.UseNuGet)
{
return Enumerable.Empty<string>();
}
return new DirectoryInfo(packageDirectory.DirInfo.FullName)
.EnumerateDirectories("*", new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive, RecurseSubdirectories = false })
.Select(d => d.FullName);
}
private void LogAllUnusedPackages(DependencyContainer dependencies) =>
GetAllPackageDirectories()
.Where(package => !dependencies.UsedPackages.Contains(package))
.ForEach(package => progressMonitor.LogInfo($"Unused package: {package}"));
private void GenerateSourceFileFromImplicitUsings()
{
var usings = new HashSet<string>();
@@ -401,7 +448,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// with this source tree. Use a SHA1 of the directory name.
/// </summary>
/// <returns>The full path of the temp directory.</returns>
private static string ComputeTempDirectory(string srcDir)
private static string ComputeTempDirectory(string srcDir, string packages = "packages")
{
var bytes = Encoding.Unicode.GetBytes(srcDir);
var sha = SHA1.HashData(bytes);
@@ -409,7 +456,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
foreach (var b in sha.Take(8))
sb.AppendFormat("{0:x2}", b);
return Path.Combine(Path.GetTempPath(), "GitHub", "packages", sb.ToString());
return Path.Combine(Path.GetTempPath(), "GitHub", packages, sb.ToString());
}
/// <summary>
@@ -587,41 +634,52 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
private bool RestoreProject(string project, bool forceDotnetRefAssemblyFetching, string? pathToNugetConfig = null) =>
dotnet.RestoreProjectToDirectory(project, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching, pathToNugetConfig);
private bool RestoreProject(string project, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, string? pathToNugetConfig = null) =>
dotnet.RestoreProjectToDirectory(project, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching, out assets, pathToNugetConfig);
private bool RestoreSolution(string solution, out IEnumerable<string> projects) =>
dotnet.RestoreSolutionToDirectory(solution, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: true, out projects);
private bool RestoreSolution(string solution, out IEnumerable<string> projects, out IEnumerable<string> assets) =>
dotnet.RestoreSolutionToDirectory(solution, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: true, out projects, out assets);
/// <summary>
/// Executes `dotnet restore` on all solution files in solutions.
/// As opposed to RestoreProjects this is not run in parallel using PLINQ
/// as `dotnet restore` on a solution already uses multiple threads for restoring
/// the projects (this can be disabled with the `--disable-parallel` flag).
/// Populates assets with the relative paths to the assets files generated by the restore.
/// Returns a list of projects that are up to date with respect to restore.
/// </summary>
/// <param name="solutions">A list of paths to solution files.</param>
private IEnumerable<string> RestoreSolutions(IEnumerable<string> solutions) =>
solutions.SelectMany(solution =>
private IEnumerable<string> RestoreSolutions(IEnumerable<string> solutions, out IEnumerable<string> assets)
{
var assetFiles = new List<string>();
var projects = solutions.SelectMany(solution =>
{
RestoreSolution(solution, out var restoredProjects);
RestoreSolution(solution, out var restoredProjects, out var a);
assetFiles.AddRange(a);
return restoredProjects;
});
assets = assetFiles;
return projects;
}
/// <summary>
/// Executes `dotnet restore` on all projects in projects.
/// This is done in parallel for performance reasons.
/// Populates assets with the relative paths to the assets files generated by the restore.
/// </summary>
/// <param name="projects">A list of paths to project files.</param>
private void RestoreProjects(IEnumerable<string> projects)
private void RestoreProjects(IEnumerable<string> projects, out IEnumerable<string> assets)
{
var assetFiles = new List<string>();
Parallel.ForEach(projects, new ParallelOptions { MaxDegreeOfParallelism = options.Threads }, project =>
{
RestoreProject(project, forceDotnetRefAssemblyFetching: true);
RestoreProject(project, forceDotnetRefAssemblyFetching: true, out var a);
assetFiles.AddRange(a);
});
assets = assetFiles;
}
private void DownloadMissingPackages(List<FileInfo> allFiles)
private void DownloadMissingPackages(List<FileInfo> allFiles, ISet<string> dllPaths)
{
var nugetConfigs = allFiles.SelectFileNamesByName("nuget.config").ToArray();
string? nugetConfig = null;
@@ -662,13 +720,15 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
return;
}
success = RestoreProject(tempDir.DirInfo.FullName, forceDotnetRefAssemblyFetching: false, pathToNugetConfig: nugetConfig);
dotnet.RestoreProjectToDirectory(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: false, out var _, pathToNugetConfig: nugetConfig);
// TODO: the restore might fail, we could retry with a prerelease (*-* instead of *) version of the package.
if (!success)
{
progressMonitor.FailedToRestoreNugetPackage(package);
}
});
dllPaths.Add(missingPackageDirectory.DirInfo.FullName);
}
private void AnalyseSolutions(IEnumerable<string> solutions)
@@ -688,26 +748,26 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
});
}
public void Dispose()
public void Dispose(TemporaryDirectory? dir, string name)
{
try
{
packageDirectory?.Dispose();
dir?.Dispose();
}
catch (Exception exc)
{
progressMonitor.LogInfo("Couldn't delete package directory: " + exc.Message);
progressMonitor.LogInfo($"Couldn't delete {name} directory {exc.Message}");
}
}
public void Dispose()
{
Dispose(packageDirectory, "package");
Dispose(legacyPackageDirectory, "legacy package");
Dispose(missingPackageDirectory, "missing package");
if (cleanupTempWorkingDirectory)
{
try
{
tempWorkingDirectory?.Dispose();
}
catch (Exception exc)
{
progressMonitor.LogInfo("Couldn't delete temporary working directory: " + exc.Message);
}
Dispose(tempWorkingDirectory, "temporary working");
}
}
}

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