Compare commits

...

188 Commits

Author SHA1 Message Date
Dave Bartolomeo
2ad4e30d9c Include hidden files 2024-09-03 11:43:34 -04:00
Dave Bartolomeo
b42064cf20 No caching 2024-09-03 11:36:01 -04:00
Dave Bartolomeo
3e73f24a47 Use channel parameter 2024-09-03 11:01:58 -04:00
Dave Bartolomeo
252f55468b Add channel parameter 2024-09-03 10:42:58 -04:00
Michael B. Gale
5e390a3b01 Merge pull request #17359 from github/mbg/bazel/dependencies/rules_go-0.50.0
Bazel/Go: Bump `rules_go` to 0.50.0
2024-09-03 14:00:18 +01:00
Michael B. Gale
c05c1d5087 Bazel: Bump rules_go to 0.50.0 2024-09-03 12:42:40 +01:00
Tom Hvitved
26c5e7b2d1 Merge pull request #17308 from hvitved/dataflow/flow-through-restriction
Data flow: Reduce non-linear recursion in `fwdFlow0`
2024-09-03 11:30:57 +02:00
Tom Hvitved
07fcd81e7e Address review comments 2024-09-03 10:13:09 +02:00
Jeroen Ketema
ffab199ea8 Merge pull request #17348 from jketema/test-fix
C++: Update expected test results after #17347
2024-09-02 21:53:13 +02:00
Jeroen Ketema
ae7bf6c97d C++: Update expected test results after #17347 2024-09-02 21:17:55 +02:00
Tom Hvitved
1057bb443f Data flow: Simplify FwdFlowIn interface 2024-09-02 16:10:34 +02:00
Simon Friis Vindum
ee6c255a7c Merge pull request #17328 from paldepind/tweak-unbounded-barrier
C++: Tweak the `bounded` barrier
2024-09-02 14:30:44 +02:00
Simon Friis Vindum
e294c8e68f Merge pull request #17347 from paldepind/test-for-uninitialized-local
C++: Add test for cpp/uninitialized-local and va_copy
2024-09-02 14:00:34 +02:00
Geoffrey White
c082c256a2 Merge pull request #17244 from geoffw0/swiftdoc2
Swift: Work around some QHelp rendering issues.
2024-09-02 12:26:23 +01:00
Simon Friis Vindum
660869e834 C++: Add test for cpp/uninitialized-local and va_copy 2024-09-02 13:25:02 +02:00
Tamás Vajk
39a73303d1 Merge pull request #17333 from github/criemen/rename-csharp
C#: Rename integration test directories.
2024-09-02 13:04:58 +02:00
Henry Mercer
4ebfafbec2 Merge pull request #17336 from github/henrymercer/rc-3.15-mergeback
Merge `rc/3.15` back into `main`
2024-09-02 11:43:19 +01:00
Tom Hvitved
642ec38589 Merge pull request #17340 from hvitved/csharp/ssa-exclude-enums 2024-08-30 16:31:38 +02:00
Tom Hvitved
4ef4ede0b1 C#: Do not calculate field-based SSA for enums 2024-08-30 11:19:07 +02:00
Tom Hvitved
a9b5faa6ab C#: Add SSA test for enums 2024-08-30 11:19:06 +02:00
Michael Nebel
89c387cf5c Merge pull request #17326 from michaelnebel/shared/contentflowtaint
DataFlow: Bugfix in content flow state for value preservation.
2024-08-30 09:23:50 +02:00
Henry Mercer
3490067316 Merge branch 'main' into henrymercer/rc-3.15-mergeback 2024-08-29 19:48:01 +01:00
Henry Mercer
d5bccd5373 Reapply "C#: Add support for flow through side-effects on static fields"
This reverts commit ea6092ad3f.
2024-08-29 19:47:53 +01:00
Cornelius Riemenschneider
092ce01d93 C#: Rename integration test directories.
We are no longer bound to the platform-specific directories, so simplify the test organization.
If you don't want this change, just skip merging this PR. It's purely optional.

This is not very invasive for C#, I'm just dropping the `only`
suffix. You could also merge all the platform-specific test dirs,
or all test dirs into the top-level directory. I'll leave that up to you.
2024-08-29 19:06:56 +02:00
Cornelius Riemenschneider
72e2910d17 Merge pull request #17315 from github/criemen/pytest-java
Java: Port all integration tests to pytest
2024-08-29 18:05:52 +02:00
Cornelius Riemenschneider
5ecc6f9dc8 Merge remote-tracking branch 'origin/main' into criemen/pytest-java 2024-08-29 16:43:46 +02:00
Cornelius Riemenschneider
dd7f757281 Address review. 2024-08-29 16:43:27 +02:00
Michael Nebel
ff31aa540c Address review comments. 2024-08-29 15:54:04 +02:00
Michael Nebel
0df0d8a51f Merge pull request #17236 from michaelnebel/java/viablecallableheuristic
Java: Make more finegrained dataflow dispatch viable callable heuristic.
2024-08-29 10:46:30 +02:00
Simon Friis Vindum
e7f059ae55 C++: Tweak the bounded barrier 2024-08-29 10:32:31 +02:00
Michael Nebel
53b2471c9d Java: Update expected test output. 2024-08-29 09:03:46 +02:00
Cornelius Riemenschneider
047a655dec Merge pull request #17324 from github/criemen/move-swift-int-tests
Swift: Move all integration tests.
2024-08-28 21:27:26 +02:00
Simon Friis Vindum
edeefe5bb6 Merge pull request #17298 from paldepind/model-functions-that-dont-throw
C++: Add basic modeling of functions that don't throw
2024-08-28 19:50:31 +02:00
Tom Hvitved
49a4f3a82f Data flow: Reduce non-linear recursion in fwdFlow0 2024-08-28 17:29:23 +02:00
Michael Nebel
fa5d6f12be Java: Update logging test expected output. 2024-08-28 16:16:16 +02:00
Michael Nebel
bd5529cefa Java: Update the Byte- and CharBuffer models and add models for set- and getParameters on LogRecord. 2024-08-28 16:15:09 +02:00
Michael Nebel
395656a1cf Java: Extend the logging test with a test case for parameters. 2024-08-28 16:13:32 +02:00
Cornelius Riemenschneider
123c375d84 Merge pull request #17322 from github/criemen/move-js-int-tests
JS: Move all integration tests.
2024-08-28 16:04:39 +02:00
Jeroen Ketema
40fe39c288 Merge pull request #17311 from jketema/builtins
C++: Add support for more clang builtins
2024-08-28 16:00:08 +02:00
Simon Friis Vindum
d1fecd869b C++: Make StringCchPrintf not extend NonThrowingFunction 2024-08-28 15:40:14 +02:00
Cornelius Riemenschneider
966c3a62dd Merge pull request #17309 from github/criemen/bazel-prerelease
Bazel: switch to a 7.4.0 prerelease.
2024-08-28 15:28:06 +02:00
Jeroen Ketema
2b571cf450 C++: Address review comments 2024-08-28 15:11:42 +02:00
Michael Nebel
e8595e28e9 Update java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2024-08-28 15:04:38 +02:00
Anders Schack-Mulligen
dd49fc932d Merge pull request #17325 from aschackmull/dataflow/state-in-summary
Dataflow: Include FlowState in SummaryCtx.
2024-08-28 15:03:18 +02:00
Cornelius Riemenschneider
ab56e63f96 Merge branch 'main' into criemen/pytest-java 2024-08-28 14:47:49 +02:00
Michael Nebel
6d346dbedd DataFlow: Bugfix in flow state for value preservation. 2024-08-28 14:40:04 +02:00
Anders Schack-Mulligen
6a9bd0de1d Dataflow: Include FlowState in SummaryCtx. 2024-08-28 14:13:28 +02:00
Jeroen Ketema
026969b6e9 C++: Add change note 2024-08-28 13:08:44 +02:00
Jeroen Ketema
9e861ce717 C++: Add support for more clang builtins 2024-08-28 13:08:42 +02:00
Tom Hvitved
7f8e6bf574 Merge pull request #16970 from hvitved/dataflow/local-big-step-stage
Data flow: Compute local big step relation as stage output
2024-08-28 12:28:16 +02:00
Tom Hvitved
27bc8ed6af Address review comment 2024-08-28 11:38:29 +02:00
Chris Smowton
464b552cad Merge pull request #17321 from github/criemen/move-go-int-tests
Go: Move all integration tests.
2024-08-28 10:30:55 +01:00
Cornelius Riemenschneider
d349ddba57 Merge pull request #17323 from github/criemen/move-ruby-int-tests
Ruby: Move all integration tests.
2024-08-28 11:18:05 +02:00
Simon Friis Vindum
d6049cd98b C++: Add additional implementations of NonThrowingFunction and make minor fixes to docs 2024-08-28 10:54:16 +02:00
Cornelius Riemenschneider
a92a845719 Swift: Move all integration tests.
We are no longer bound to the platform-specific directories,
so simplify the test organization.
If you don't want this change, just skip merging this PR. It's purely optional.
2024-08-28 10:47:17 +02:00
Cornelius Riemenschneider
3326bc417c Ruby: Move all integration tests.
We no longer need the platform-specific directories, so simplify the test organization.
If you don't want this change, just skip merging this PR. It's purely optional.
2024-08-28 10:45:05 +02:00
Cornelius Riemenschneider
b7b475d13b JS: Move all integration tests.
We no longer need the platform-specific directories, so simplify the test organization.
If you don't want this change, just skip merging this PR.
It's purely optional.

The PR also deletes a spurious qlpack.yml that I missed when converting the tests to pytest.
2024-08-28 10:43:08 +02:00
Cornelius Riemenschneider
bfc6fee828 Go: Move all integration tests.
We no longer need the platform-specific directories,
so simplify the test organization.
If you want to retain the `linux` directory for two tests,
or not do this at all, just skip merging this PR.
It's purely optional.
2024-08-28 10:37:59 +02:00
Tom Hvitved
22e1921391 Merge pull request #17313 from hvitved/dataflow/to-normal-sink-node-ex
Data flow: Move `toNormalSinkNodeEx` into `PathNodeMid`
2024-08-28 09:06:41 +02:00
Henry Mercer
ea1870fbbd Merge pull request #17318 from github/post-release-prep/codeql-cli-2.18.3
Post-release preparation for codeql-cli-2.18.3
2024-08-27 20:34:55 +01:00
Henry Mercer
21a0109ca2 Merge branch 'rc/3.15' into post-release-prep/codeql-cli-2.18.3 2024-08-27 19:53:46 +01:00
github-actions[bot]
3e774476c6 Post-release preparation for codeql-cli-2.18.3 2024-08-27 18:52:31 +00:00
Tom Hvitved
b589fcad11 Data flow: Tweak join-order in toNormalSinkNodeEx 2024-08-27 15:42:24 +02:00
Tom Hvitved
80b6135a64 Data flow: Move toNormalSinkNodeEx into PathNodeMid 2024-08-27 15:42:13 +02:00
Michael Nebel
15b06907dd Java: Updated expected test output. 2024-08-27 14:48:14 +02:00
Michael Nebel
8f734ad1b2 Java: Tighten the criteria for when we disregard generated models. 2024-08-27 14:48:11 +02:00
Michael Nebel
021fd1450e Java: Add some dispatch examples to the external flow step test. 2024-08-27 14:48:03 +02:00
Michael Nebel
43b52a0921 Java: Add change note. 2024-08-27 13:28:18 +02:00
Michael Nebel
7488cc0811 Java: Updated expected test output. 2024-08-27 13:28:13 +02:00
Michael Nebel
d79aa294ec Java: Move some neutrals into the model.yml file (they have previosly been ignored due to wrong file extension). 2024-08-27 13:28:09 +02:00
Michael Nebel
db51604f46 Java: Promote some generated models and add some manual neutrals. 2024-08-27 13:28:05 +02:00
Michael Nebel
6cb5e13a23 Java: Re-factor tests and update expected test output. 2024-08-27 13:28:00 +02:00
Michael Nebel
68880b2056 Java: Update expected test output. Generated models are no longer applied as there exist a source implementation. 2024-08-27 13:27:55 +02:00
Michael Nebel
fe6693739a Java: Make more finegrained dataflow dispatch viable callable heuristic. 2024-08-27 13:27:52 +02:00
Cornelius Riemenschneider
1c3b9f7031 Delete legacy test utils. 2024-08-27 13:14:24 +02:00
Cornelius Riemenschneider
c69df1a6e3 Port java integration tests to pytest.
Some notes:
* These tests rely on a variety of fixtures
* The previous maven-wrapper checks were checking for the version of maven installed by looking at the checked-in wrapper script. I dropped this behavior.
* I replaced a lot of test queries that queried for a (subset of) source archive files with the source_archive fixture. In particular, tests that excluded properties files from being listed in the expected output now include them.
   It's much faster to generate this list via the fixture instead of using CodeQL for it.
2024-08-27 13:14:23 +02:00
Cornelius Riemenschneider
5fa30c33b8 Remove legacy java files. 2024-08-27 13:14:21 +02:00
Cornelius Riemenschneider
19606b1903 Add *.actual to the gitignore file.
This is also used by the integration tests.
2024-08-27 13:14:20 +02:00
Ian Lynagh
3a864d3de2 Merge pull request #17292 from igfoo/igfoo/open
Kotlin: Remove a redundant 'open'
2024-08-27 12:14:04 +01:00
Ian Lynagh
085bf2f662 Merge pull request #17293 from igfoo/igfoo/dtw
Kotlin: Restrict some TrapWriter types to DiagnosticTrapWriter
2024-08-27 12:13:59 +01:00
Cornelius Riemenschneider
123507e2dc No need to disable the layering check anymore, this was fixed upstream. 2024-08-27 13:00:56 +02:00
Cornelius Riemenschneider
62219fae60 Bazel: switch to a 7.4.0 prerelease. 2024-08-27 12:27:53 +02:00
Henry Mercer
e0013eec1b Merge pull request #17294 from github/codeql-cli-2.18.3
Merge `codeql-cli-2.18.3` back into `rc/3.15`
2024-08-27 10:46:05 +01:00
Michael Nebel
287857c5db Merge pull request #17301 from michaelnebel/shared/contentflowbadjoin
Shared: Fix bad join in content flow.
2024-08-27 10:17:04 +02:00
Paolo Tranquilli
b79be718e1 Merge pull request #17306 from github/redsun82/bazel-lfs
Bazel: fix logging bug in `git_lfs_probe.py`
2024-08-27 09:42:39 +02:00
Anders Schack-Mulligen
b3fa4f3d9e Merge pull request #17289 from aschackmull/dataflow/summaryctx
Dataflow: Simplify using a SummaryCtx type.
2024-08-27 09:32:43 +02:00
Paolo Tranquilli
0738e01e7e Bazel: fix logging bug in git_lfs_probe.py
The case of an `HTTPError` was printed to stdout (and therefore globbed
by bazel).

While I'm at it, I also introduced a timeout to `urlopen` and improved
the `no endpoints found` error message.
2024-08-27 09:12:37 +02:00
Michael Nebel
e81fdc951a Merge pull request #17246 from michaelnebel/modelgendebug
C#/Java: Add some model generator summary debugging queries.
2024-08-26 16:13:03 +02:00
Michael Nebel
77bfe39ca7 Shared: Address review comments. 2024-08-26 15:24:56 +02:00
Michael Nebel
4381bae5d1 Shared: Fix bad join. 2024-08-26 15:24:54 +02:00
Anders Schack-Mulligen
d8c8bcd386 Dataflow: Tweak qldoc. 2024-08-26 15:12:37 +02:00
Anders Schack-Mulligen
cbb58d0041 Dataflow: Add a getLocation rootdef. 2024-08-26 15:05:30 +02:00
Michael Nebel
34d83a6b0d C#/Java: Address review comments. 2024-08-26 15:02:27 +02:00
Simon Friis Vindum
d9dbcdba34 C++: Fix imports 2024-08-26 12:42:44 +02:00
Asger F
4e3440aad0 Merge pull request #17275 from asgerf/cpp/taint-test-case-false-negative
C++: Reveal false negative in test case
2024-08-26 12:36:03 +02:00
Asger F
16c2cf24b3 C++: use inline annotation for missing flow 2024-08-26 11:53:31 +02:00
Asger F
592e2eafb6 Merge pull request #17262 from asgerf/shared/implicit-read
Shared: restrict flow after using implicit read
2024-08-26 11:48:50 +02:00
Tom Hvitved
e5d626f907 Data flow: Only recompute local big step in stage 6 2024-08-26 09:58:29 +02:00
Simon Friis Vindum
128053e214 C++: Add basic modeling of functions that don't throw 2024-08-26 09:37:44 +02:00
Tom Hvitved
c92c96fa78 Data flow: Compute local big step relation per stage 2024-08-26 09:15:27 +02:00
Paolo Tranquilli
c4c8c9ddc1 Merge pull request #17291 from github/criemen/ripunzip
Make ripunzip installer accessible from outside this repo.
2024-08-23 20:14:44 +02:00
Cornelius Riemenschneider
3ac8108c4a Address review. 2024-08-23 17:26:05 +02:00
Ian Lynagh
6a7d8b5301 Kotlin: Restrict some TrapWriter types to DiagnosticTrapWriter
We never use the greater generality, so this makes it easier to see
what's happening.
2024-08-23 15:41:21 +01:00
Ian Lynagh
7d500cf58c Kotlin: Remove a redundant 'open' 2024-08-23 15:08:10 +01:00
Tamás Vajk
d710c1e89d Merge pull request #17287 from tamasvajk/message-count-telemetry
C#: Add aggregated compiler and extractor message counts to extractio…
2024-08-23 14:41:27 +02:00
Cornelius Riemenschneider
d84e745ce9 Make ripunzip installer accessible from outside this repo.
* The relative path to misc doesn't work when running from another repo
* The buildifier dependency is not available from other repos,
  therefore we can't pull in //misc/bazel without further refactoring.

Therefore, inline the runfiles snippet here.
2024-08-23 14:24:51 +02:00
Anders Schack-Mulligen
65189e09f5 Dataflow: Simplify using a SummaryCtx type. 2024-08-23 14:18:46 +02:00
Asger F
8df7fbf6d6 Swift: update test output
The 'first' field is seen as a TaintInheritingContent, which means any read step for 'first' becomes a taint step too.
This type of taint step does not permit an implicit read before it, because it wasn't contributed by a configuration.
So there is no way for the taint to get out of the collection content before the taint step through '.first'.
The test previously passed because an implicit read at once of the earlier sinks could follow use-use flow down to the receiver of .first,
allowing it to escape the collection content.
2024-08-23 11:30:50 +02:00
Asger F
d27b28d371 C++: update test output
This reveals that some tests were passing for the wrong reasons.
See https://github.com/github/codeql/pull/17275
2024-08-23 11:29:24 +02:00
Asger F
9703f67794 Test output updates that only affect nodes/edges 2024-08-23 11:03:26 +02:00
Asger F
6bc8407bd6 Java: Update test output 2024-08-23 11:02:29 +02:00
Asger F
c3b36325b2 Shared: prevent use-use flow through implicit reads (part 1) 2024-08-23 11:02:28 +02:00
Michael Nebel
20d9fd11ac Merge pull request #17288 from michaelnebel/shared/contentflow
Shared: ContentFlow.
2024-08-23 09:52:27 +02:00
Michael Nebel
19c2eb17c4 C#: Remove redundant imports. 2024-08-23 09:04:13 +02:00
Chris Smowton
67d94376e8 Merge pull request #17227 from smowton/smowton/fix/baseline-vs-nonroot-vendor-dirs
Go / configure-baseline: account for multiple vendor directories and the `CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS` setting
2024-08-22 15:00:51 +01:00
Michael Nebel
d935c47231 C#: Use the shared content flow implementation. 2024-08-22 15:46:01 +02:00
Michael Nebel
e6424f0f45 Shared: Make ContentDataFlow reusable. 2024-08-22 15:45:58 +02:00
Owen Mansel-Chan
18b99ffecc Merge pull request #17284 from owen-mc/go/fix-frameworks-coverage
Go: Try to fix packages in frameworks coverage
2024-08-22 14:43:52 +01:00
Tamas Vajk
6827bedaa7 C#: Add aggregated compiler and extractor message counts to extraction telemetry query 2024-08-22 15:14:33 +02:00
Tamás Vajk
3dce56b0b1 Merge pull request #17276 from tamasvajk/impr/change-partial-method-location
C#: Change reporting location of partial methods
2024-08-22 15:10:21 +02:00
Michael Nebel
4cd34531c6 Shared: Add a copy of the existing C# Content Dataflow implementation. 2024-08-22 15:07:45 +02:00
Owen Mansel-Chan
2edadbf423 Try to fix packages in frameworks coverage 2024-08-22 11:44:34 +01:00
Asger F
a1688f6a1a Merge pull request #17240 from knewbury01/knewbury01/fix-helmetrequiredsetting-model
Update JS helmet model structure
2024-08-22 11:59:28 +02:00
Asger F
81239dcd95 Java: add test case 2024-08-22 11:26:05 +02:00
Michael Nebel
bd69b96752 Merge pull request #17273 from michaelnebel/csharp/sqlinject
C#: ASP.NET Controller is allowed to be abstract.
2024-08-22 11:18:48 +02:00
Asger F
43f54db4db Merge pull request #17274 from asgerf/java/implicit-pending-intents-implicit-read
Java: Reveal false negative in test
2024-08-22 11:00:07 +02:00
Tom Hvitved
d41d7c8246 Merge pull request #17207 from hvitved/csharp/content-set
C#: Implement `ContentSet`
2024-08-22 10:55:11 +02:00
Tom Hvitved
a213982b48 Merge pull request #17222 from hvitved/ruby/hash-splat-param-arg-matching
Ruby: Rework (hash) splat argument/parameter matching
2024-08-22 10:54:52 +02:00
Asger F
09aca6b47e Merge pull request #17212 from mbaluda/main
Add support for importing NPM modules in XSJS sources
2024-08-22 10:54:33 +02:00
Anders Schack-Mulligen
d97a301fef Merge pull request #17105 from aschackmull/dataflow/stage6
Dataflow: Refactor stage 6 to use shared stage code.
2024-08-22 09:46:49 +02:00
Tom Hvitved
e94fabcc19 Address review comment 2024-08-22 08:27:15 +02:00
Henry Mercer
55d325148d Merge pull request #17280 from github/post-release-prep/codeql-cli-2.18.3
Post-release preparation for codeql-cli-2.18.3
2024-08-21 21:34:50 +01:00
github-actions[bot]
0724fd7ce2 Post-release preparation for codeql-cli-2.18.3 2024-08-21 18:25:54 +00:00
Tom Hvitved
cb1b1da422 Ruby: Add another array flow test 2024-08-21 19:06:53 +02:00
Tom Hvitved
b0003c0453 Ruby: Remove two redundant checks 2024-08-21 19:06:29 +02:00
Tamas Vajk
f7bf5e89be Add change note 2024-08-21 15:58:05 +02:00
Tamas Vajk
7c4733e88f C#: Change reporting location of partial methods 2024-08-21 15:13:14 +02:00
Michael Nebel
7049499e95 C#: Add change-note. 2024-08-21 14:38:55 +02:00
Asger F
3aa32e4aff Java: use MISSING inline annotation 2024-08-21 13:40:40 +02:00
Asger F
f7ea8a1563 Java: trivial result set re-order 2024-08-21 13:37:38 +02:00
Asger F
5751fc2d3a Java: Reveal false negative in test
One of the sinks was flagged for the wrong reason in the test case.

The flow into the 'startActivities' sink isn't working properly, but this was not revealed by the test since an alternate, spurious path exists. The spurious path goes through the implicit read at the prior sink and takes a use-use step to the 'startActivities' sink. Swapping the order of the two sinks reveals the false negative.
2024-08-21 13:36:47 +02:00
Michael Nebel
45d4d5138a C#: Update expected test output. 2024-08-21 13:14:12 +02:00
Michael Nebel
79718f1cd6 C#: Remove requirement that a controller is not allowed to be abstract. 2024-08-21 13:00:15 +02:00
Michael Nebel
75772c5832 C#: Add abstract controller remote flow source example. 2024-08-21 13:00:10 +02:00
Michael Nebel
5d14307ea2 C#: Add a SQL injection test case for ASP.NET. 2024-08-21 12:14:30 +02:00
Chris Smowton
f13f19d5dc Fix typo 2024-08-21 10:22:42 +01:00
Chris Smowton
2939cefc68 Use platform path separators for file testing, and forward-slashes for reporting to CodeQL 2024-08-21 10:15:44 +01:00
Chris Smowton
c99a84689b Switch test expectations to use unix-style paths 2024-08-21 09:56:08 +01:00
Anders Schack-Mulligen
525b6f30e3 C++/C#/Java: Accept test changes. 2024-08-21 10:51:28 +02:00
Anders Schack-Mulligen
5fbdd83a23 Dataflow: Rename StagePathNode to PathNode. 2024-08-21 10:51:28 +02:00
Anders Schack-Mulligen
273c0bd121 Dataflow: Delete dead code. 2024-08-21 10:51:28 +02:00
Anders Schack-Mulligen
1787bcb05a Dataflow: Replace PathNode with Stage implementation. 2024-08-21 10:51:24 +02:00
Anders Schack-Mulligen
74739bedfc Dataflow: Add Stage 6 instantiation. 2024-08-21 10:44:46 +02:00
Anders Schack-Mulligen
831a66d812 Dataflow: Add getANonHiddenSuccessor to StagePathNodeImpl. 2024-08-21 10:44:45 +02:00
Anders Schack-Mulligen
e594e7283d Dataflow: Check stateful in/out-barriers in each stage. 2024-08-21 10:44:45 +02:00
Anders Schack-Mulligen
c2b25c7f2b Dataflow: Check clearsContent on store targets in StagePathGraph. 2024-08-21 10:44:44 +02:00
Anders Schack-Mulligen
b8d0b691da Dataflow: Introduce sink projection and add successor as member predicate. 2024-08-21 10:44:44 +02:00
Anders Schack-Mulligen
bc1dd45d4f Dataflow: Make private 2024-08-21 10:44:43 +02:00
Anders Schack-Mulligen
9429e5ccba Dataflow: Update StagePathNode.toString. 2024-08-21 10:44:43 +02:00
Anders Schack-Mulligen
81a815c343 Dataflow: Add StagePathNode.getState. 2024-08-21 10:44:43 +02:00
Anders Schack-Mulligen
bdcc5e7b67 Dataflow: Refactor getLocation 2024-08-21 10:44:42 +02:00
Anders Schack-Mulligen
bc0ae4cd1e Dataflow: Replace StagePathNode.getNode with getNodeEx. 2024-08-21 10:44:42 +02:00
Anders Schack-Mulligen
9bd3f3dee0 Dataflow: Rename StagePathNode to StagePathNodeImpl. 2024-08-21 10:44:41 +02:00
Chris Smowton
fc301206d1 Change note 2024-08-20 17:11:58 +01:00
Chris Smowton
3acab640b2 Add configure-baseline integration test 2024-08-20 17:07:09 +01:00
Chris Smowton
15b5bcc67c Output to stdout, not stderr 2024-08-20 17:01:54 +01:00
Chris Smowton
8b9617cd38 Update bazel build files 2024-08-20 15:56:28 +01:00
Chris Smowton
ea3e5c8a99 Clarify comment 2024-08-20 15:56:27 +01:00
Chris Smowton
f1f6f9b580 Share vendor-dir extraction logic between extractor and configure-baseline script 2024-08-20 15:56:26 +01:00
Chris Smowton
22802fd41f Improve struct naming 2024-08-20 15:56:25 +01:00
Chris Smowton
5d34dbf2c2 Remove unnecessary batch script flag 2024-08-20 15:56:24 +01:00
Chris Smowton
624d2b83c0 Tidy comments 2024-08-20 15:56:23 +01:00
Chris Smowton
21366dd502 Go / configure-baseline: account for multiple vendor directories and the CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS setting
Our existing configure-baseline scripts would give the wrong result if a `vendor` directory wasn't at the root of the repository, or if the `CODEQL_EXTRACTOR_GO_EXTRACT_VENDOR_DIRS` variable was set to `true` indicating the user wants their vendored code scanned.

Here I replace the shell scripts that implemented the very simplest behaviour with a small Go program.
2024-08-20 15:56:22 +01:00
Michael Nebel
6ea01b81bb C#: Add some summary debugging queries. 2024-08-20 16:28:18 +02:00
Michael Nebel
fd311d5143 Java: Add some summary debugging queries. 2024-08-20 16:28:15 +02:00
Tom Hvitved
d15e1b5598 Ruby: Prevent synthetic splat matching for actual splats at same positions 2024-08-20 16:21:59 +02:00
Tom Hvitved
c4b0f81883 Ruby: Prevent positional matching when preceded by a splat 2024-08-20 16:21:58 +02:00
Tom Hvitved
20dc242830 Ruby: Rework hash splat argument/parameter matching 2024-08-20 16:21:57 +02:00
Tom Hvitved
6d4f3bd014 Ruby: Rework splat argument/parameter matching 2024-08-20 16:21:56 +02:00
Geoffrey White
0088ece3ea Revert "Swift: Fix two of the qhelps by slightly modifying the sample code instead."
This reverts commit 2d19d6f61e.
2024-08-16 13:24:03 +01:00
Geoffrey White
2d19d6f61e Swift: Fix two of the qhelps by slightly modifying the sample code instead. 2024-08-16 12:57:32 +01:00
Geoffrey White
0126fbcb8f Swift: Clear the language for Swift code snippets that are rendering incorrectly. 2024-08-16 10:56:46 +01:00
Asger F
7dcdad066f Update javascript/ql/lib/semmle/javascript/frameworks/helmet/Helmet.qll 2024-08-16 09:44:53 +02:00
Kristen Newbury
81787a159e Add QL docs to helmet model 2024-08-15 16:32:37 -04:00
Kristen Newbury
e84dda4fa6 Update JS helmet model structure 2024-08-15 16:08:48 -04:00
Tom Hvitved
d638b5c7d4 Sync shared file 2024-08-13 15:27:38 +02:00
Tom Hvitved
f6ec56a977 C#: Implement ContentSet 2024-08-13 15:27:36 +02:00
Mauro Baluda
be0a60a7f6 Add support for importing NPM modules in XSJS sources 2024-08-13 14:45:03 +02:00
1123 changed files with 15656 additions and 12015 deletions

View File

@@ -1 +1 @@
7.2.1 5f5d70b6c4d2fb1a889479569107f1692239e8a7

View File

@@ -24,5 +24,5 @@ jobs:
extra_args: > extra_args: >
buildifier --all-files 2>&1 || buildifier --all-files 2>&1 ||
( (
echo -e "In order to format all bazel files, please run:\n bazel run //misc/bazel:buildifier"; exit 1 echo -e "In order to format all bazel files, please run:\n bazel run //misc/bazel/buildifier"; exit 1
) )

View File

@@ -48,7 +48,7 @@ jobs:
- name: "Build Swift extractor using Bazel" - name: "Build Swift extractor using Bazel"
run: | run: |
bazel clean --expunge bazel clean --expunge
bazel run //swift:create-extractor-pack --nouse_action_cache --noremote_accept_cached --noremote_upload_local_results --spawn_strategy=local --features=-layering_check bazel run //swift:create-extractor-pack --nouse_action_cache --noremote_accept_cached --noremote_upload_local_results --spawn_strategy=local
bazel shutdown bazel shutdown
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis

View File

@@ -26,6 +26,10 @@ on:
tag: tag:
description: "Version tag to create" description: "Version tag to create"
required: false required: false
channel:
description: Channel from which to download the CodeQL CLI (defaults to 'nightly')
required: false
default: nightly
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
@@ -116,11 +120,8 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Fetch CodeQL - name: Fetch CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql
- name: Cache compilation cache
id: query-cache
uses: ./.github/actions/cache-query-compilation
with: with:
key: ruby-build channel: ${{ github.event.inputs.channel }}
- name: Build Query Pack - name: Build Query Pack
run: | run: |
PACKS=${{ runner.temp }}/query-packs PACKS=${{ runner.temp }}/query-packs
@@ -140,6 +141,7 @@ jobs:
path: | path: |
${{ runner.temp }}/query-packs/* ${{ runner.temp }}/query-packs/*
retention-days: 1 retention-days: 1
include-hidden-files: true
package: package:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -176,6 +178,7 @@ jobs:
name: codeql-ruby-pack name: codeql-ruby-pack
path: ruby/codeql-ruby.zip path: ruby/codeql-ruby.zip
retention-days: 1 retention-days: 1
include-hidden-files: true
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v3
with: with:
name: codeql-ruby-queries name: codeql-ruby-queries
@@ -193,6 +196,7 @@ jobs:
name: codeql-ruby-bundle name: codeql-ruby-bundle
path: ruby/codeql-ruby-bundle.zip path: ruby/codeql-ruby-bundle.zip
retention-days: 1 retention-days: 1
include-hidden-files: true
test: test:
defaults: defaults:
@@ -209,6 +213,8 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Fetch CodeQL - name: Fetch CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql
with:
channel: ${{ github.event.inputs.channel }}
- name: Download Ruby bundle - name: Download Ruby bundle
uses: actions/download-artifact@v3 uses: actions/download-artifact@v3

2
.gitignore vendored
View File

@@ -7,8 +7,8 @@
.cache .cache
# qltest projects and artifacts # qltest projects and artifacts
*.actual
*/ql/test/**/*.testproj */ql/test/**/*.testproj
*/ql/test/**/*.actual
*/ql/test/**/go.sum */ql/test/**/go.sum
# Visual studio temporaries, except a file used by QL4VS # Visual studio temporaries, except a file used by QL4VS

View File

@@ -26,7 +26,7 @@ repos:
name: Format bazel files name: Format bazel files
files: \.(bazel|bzl) files: \.(bazel|bzl)
language: system language: system
entry: bazel run //misc/bazel:buildifier entry: bazel run //misc/bazel/buildifier
pass_filenames: false pass_filenames: false
# DISABLED: can be enabled by copying this config and installing `pre-commit` with `--config` on the copy # DISABLED: can be enabled by copying this config and installing `pre-commit` with `--config` on the copy

View File

@@ -15,7 +15,7 @@ local_path_override(
# see https://registry.bazel.build/ for a list of available packages # see https://registry.bazel.build/ for a list of available packages
bazel_dep(name = "platforms", version = "0.0.10") bazel_dep(name = "platforms", version = "0.0.10")
bazel_dep(name = "rules_go", version = "0.49.0") bazel_dep(name = "rules_go", version = "0.50.0")
bazel_dep(name = "rules_pkg", version = "0.10.1") bazel_dep(name = "rules_pkg", version = "0.10.1")
bazel_dep(name = "rules_nodejs", version = "6.2.0-codeql.1") bazel_dep(name = "rules_nodejs", version = "6.2.0-codeql.1")
bazel_dep(name = "rules_python", version = "0.32.2") bazel_dep(name = "rules_python", version = "0.32.2")

View File

@@ -0,0 +1,17 @@
class Expr extends @expr {
string toString() { none() }
}
class Location extends @location_expr {
string toString() { none() }
}
predicate isExprWithNewBuiltin(Expr expr) {
exists(int kind | exprs(expr, kind, _) | 385 <= kind and kind <= 388)
}
from Expr expr, int kind, int kind_new, Location location
where
exprs(expr, kind, location) and
if isExprWithNewBuiltin(expr) then kind_new = 1 else kind_new = kind
select expr, kind_new, location

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,14 @@
class Expr extends @expr {
string toString() { none() }
}
class Type extends @type {
string toString() { none() }
}
from Expr expr, Type type, int kind
where
sizeof_bind(expr, type) and
exprs(expr, kind, _) and
(kind = 93 or kind = 94)
select expr, type

View File

@@ -0,0 +1,4 @@
description: Add new builtin operations
compatibility: partial
exprs.rel: run exprs.qlo
sizeof_bind.rel: run sizeof_bind.qlo

View File

@@ -0,0 +1,5 @@
---
category: feature
---
* Added subclasses of `BuiltInOperations` for the `__is_scoped_enum`, `__is_trivially_equality_comparable`, and `__is_trivially_relocatable` builtin operations.
* Added a subclass of `Expr` for `__datasizeof` expressions.

View File

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

View File

@@ -1885,3 +1885,59 @@ class BuiltInOperationIsWinInterface extends BuiltInOperation, @iswininterface {
override string getAPrimaryQlClass() { result = "BuiltInOperationIsWinInterface" } override string getAPrimaryQlClass() { result = "BuiltInOperationIsWinInterface" }
} }
/**
* A C++ `__is_trivially_equality_comparable` built-in operation.
*
* Returns `true` if comparing two objects of type `_Tp` is equivalent to
* comparing their object representations.
*
* ```
* template<typename _Tp>
* struct is_trivially_equality_comparable
* : public integral_constant<bool, __is_trivially_equality_comparable(_Tp)>
* {};
* ```
*/
class BuiltInOperationIsTriviallyEqualityComparable extends BuiltInOperation,
@istriviallyequalitycomparable
{
override string toString() { result = "__is_trivially_equality_comparable" }
override string getAPrimaryQlClass() { result = "BuiltInOperationIsTriviallyEqualityComparable" }
}
/**
* A C++ `__is_scoped_enum` built-in operation (used by some implementations
* of the `<type_traits>` header).
*
* Returns `true` if a type is a scoped enum.
* ```
* template<typename _Tp>
* constexpr bool is_scoped_enum = __is_scoped_enum(_Tp);
* ```
*/
class BuiltInOperationIsScopedEnum extends BuiltInOperation, @isscopedenum {
override string toString() { result = "__is_scoped_enum" }
override string getAPrimaryQlClass() { result = "BuiltInOperationIsScopedEnum" }
}
/**
* A C++ `__is_trivially_relocatable` built-in operation.
*
* Returns `true` if moving an object of type `_Tp` is equivalent to
* copying the underlying bytes.
*
* ```
* template<typename _Tp>
* struct is_trivially_relocatable
* : public integral_constant<bool, __is_trivially_relocatable(_Tp)>
* {};
* ```
*/
class BuiltInOperationIsTriviallyRelocatable extends BuiltInOperation, @istriviallyrelocatable {
override string toString() { result = "__is_trivially_relocatable" }
override string getAPrimaryQlClass() { result = "BuiltInOperationIsTriviallyRelocatable" }
}

View File

@@ -791,6 +791,53 @@ class AlignofTypeOperator extends AlignofOperator {
override string toString() { result = "alignof(" + this.getTypeOperand().getName() + ")" } override string toString() { result = "alignof(" + this.getTypeOperand().getName() + ")" }
} }
/**
* A C++ `__datasizeof` expression (used by some implementations
* of the `<type_traits>` header).
*
* The `__datasizeof` expression behaves identically to `sizeof` except
* that the result ignores tail padding.
*/
class DatasizeofOperator extends Expr, @datasizeof {
override int getPrecedence() { result = 16 }
}
/**
* A C++ `__datasizeof` expression whose operand is an expression.
*/
class DatasizeofExprOperator extends DatasizeofOperator {
DatasizeofExprOperator() { exists(this.getChild(0)) }
override string getAPrimaryQlClass() { result = "DatasizeofExprOperator" }
/** Gets the contained expression. */
Expr getExprOperand() { result = this.getChild(0) }
override string toString() { result = "__datasizeof(<expr>)" }
override predicate mayBeImpure() { this.getExprOperand().mayBeImpure() }
override predicate mayBeGloballyImpure() { this.getExprOperand().mayBeGloballyImpure() }
}
/**
* A C++ `__datasizeof` expression whose operand is a type name.
*/
class DatasizeofTypeOperator extends DatasizeofOperator {
DatasizeofTypeOperator() { sizeof_bind(underlyingElement(this), _) }
override string getAPrimaryQlClass() { result = "DatasizeofTypeOperator" }
/** Gets the contained type. */
Type getTypeOperand() { sizeof_bind(underlyingElement(this), unresolveElement(result)) }
override string toString() { result = "__datasizeof(" + this.getTypeOperand().getName() + ")" }
override predicate mayBeImpure() { none() }
override predicate mayBeGloballyImpure() { none() }
}
/** /**
* A C/C++ array to pointer conversion. * A C/C++ array to pointer conversion.
* *

View File

@@ -304,6 +304,8 @@ class Expr extends StmtParent, @expr {
e instanceof NoExceptExpr e instanceof NoExceptExpr
or or
e instanceof AlignofOperator e instanceof AlignofOperator
or
e instanceof DatasizeofOperator
) )
or or
exists(Decltype d | d.getExpr() = this.getParentWithConversions*()) exists(Decltype d | d.getExpr() = this.getParentWithConversions*())

View File

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

View File

@@ -9,13 +9,14 @@ import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.NonThrowing
/** /**
* The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant * The standard functions `memcpy`, `memmove` and `bcopy`; and the gcc variant
* `__builtin___memcpy_chk`. * `__builtin___memcpy_chk`.
*/ */
private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction, private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffectFunction,
AliasFunction AliasFunction, NonThrowingFunction
{ {
MemcpyFunction() { MemcpyFunction() {
// memcpy(dest, src, num) // memcpy(dest, src, num)

View File

@@ -8,9 +8,10 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.NonThrowing
private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, AliasFunction, private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, AliasFunction,
SideEffectFunction SideEffectFunction, NonThrowingFunction
{ {
MemsetFunctionModel() { MemsetFunctionModel() {
this.hasGlobalOrStdOrBslName("memset") this.hasGlobalOrStdOrBslName("memset")

View File

@@ -0,0 +1,11 @@
import semmle.code.cpp.models.interfaces.NonThrowing
/**
* A function that is annotated with a `noexcept` specifier (or the equivalent
* `throw()` specifier) guaranteeing that the function can not throw exceptions.
*
* Note: The `throw` specifier was deprecated in C++11 and removed in C++17.
*/
class NoexceptFunction extends NonThrowingFunction {
NoexceptFunction() { this.isNoExcept() or this.isNoThrow() }
}

View File

@@ -8,11 +8,12 @@
import semmle.code.cpp.models.interfaces.FormattingFunction import semmle.code.cpp.models.interfaces.FormattingFunction
import semmle.code.cpp.models.interfaces.Alias import semmle.code.cpp.models.interfaces.Alias
import semmle.code.cpp.models.interfaces.SideEffect import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.NonThrowing
/** /**
* The standard functions `printf`, `wprintf` and their glib variants. * The standard functions `printf`, `wprintf` and their glib variants.
*/ */
private class Printf extends FormattingFunction, AliasFunction { private class Printf extends FormattingFunction, AliasFunction, NonThrowingFunction {
Printf() { Printf() {
this instanceof TopLevelFunction and this instanceof TopLevelFunction and
( (
@@ -36,7 +37,7 @@ private class Printf extends FormattingFunction, AliasFunction {
/** /**
* The standard functions `fprintf`, `fwprintf` and their glib variants. * The standard functions `fprintf`, `fwprintf` and their glib variants.
*/ */
private class Fprintf extends FormattingFunction { private class Fprintf extends FormattingFunction, NonThrowingFunction {
Fprintf() { Fprintf() {
this instanceof TopLevelFunction and this instanceof TopLevelFunction and
( (
@@ -54,7 +55,7 @@ private class Fprintf extends FormattingFunction {
/** /**
* The standard function `sprintf` and its Microsoft and glib variants. * The standard function `sprintf` and its Microsoft and glib variants.
*/ */
private class Sprintf extends FormattingFunction { private class Sprintf extends FormattingFunction, NonThrowingFunction {
Sprintf() { Sprintf() {
this instanceof TopLevelFunction and this instanceof TopLevelFunction and
( (
@@ -97,7 +98,7 @@ private class Sprintf extends FormattingFunction {
/** /**
* Implements `Snprintf`. * Implements `Snprintf`.
*/ */
private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction { private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction, NonThrowingFunction {
SnprintfImpl() { SnprintfImpl() {
this instanceof TopLevelFunction and this instanceof TopLevelFunction and
( (
@@ -204,7 +205,7 @@ private class StringCchPrintf extends FormattingFunction {
/** /**
* The standard function `syslog`. * The standard function `syslog`.
*/ */
private class Syslog extends FormattingFunction { private class Syslog extends FormattingFunction, NonThrowingFunction {
Syslog() { Syslog() {
this instanceof TopLevelFunction and this instanceof TopLevelFunction and
this.hasGlobalName("syslog") and this.hasGlobalName("syslog") and

View File

@@ -7,13 +7,16 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.SideEffect import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.NonThrowing
/** /**
* The standard function `strcat` and its wide, sized, and Microsoft variants. * The standard function `strcat` and its wide, sized, and Microsoft variants.
* *
* Does not include `strlcat`, which is covered by `StrlcatFunction` * Does not include `strlcat`, which is covered by `StrlcatFunction`
*/ */
class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction { class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, SideEffectFunction,
NonThrowingFunction
{
StrcatFunction() { StrcatFunction() {
this.hasGlobalOrStdOrBslName([ this.hasGlobalOrStdOrBslName([
"strcat", // strcat(dst, src) "strcat", // strcat(dst, src)

View File

@@ -7,11 +7,14 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.DataFlow
import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.SideEffect import semmle.code.cpp.models.interfaces.SideEffect
import semmle.code.cpp.models.interfaces.NonThrowing
/** /**
* The standard function `strcpy` and its wide, sized, and Microsoft variants. * The standard function `strcpy` and its wide, sized, and Microsoft variants.
*/ */
class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, SideEffectFunction { class StrcpyFunction extends ArrayFunction, DataFlowFunction, TaintFunction, SideEffectFunction,
NonThrowingFunction
{
StrcpyFunction() { StrcpyFunction() {
this.hasGlobalOrStdOrBslName([ this.hasGlobalOrStdOrBslName([
"strcpy", // strcpy(dst, src) "strcpy", // strcpy(dst, src)

View File

@@ -0,0 +1,11 @@
/**
* Provides an abstract class for modeling functions that never throw.
*/
import semmle.code.cpp.Function
import semmle.code.cpp.models.Models
/**
* A function that is guaranteed to never throw.
*/
abstract class NonThrowingFunction extends Function { }

View File

@@ -1788,6 +1788,10 @@ case @expr.kind of
| 382 = @isvalidwinrttype | 382 = @isvalidwinrttype
| 383 = @iswinclass | 383 = @iswinclass
| 384 = @iswininterface | 384 = @iswininterface
| 385 = @istriviallyequalitycomparable
| 386 = @isscopedenum
| 387 = @istriviallyrelocatable
| 388 = @datasizeof
; ;
@var_args_expr = @vastartexpr @var_args_expr = @vastartexpr
@@ -1901,6 +1905,9 @@ case @expr.kind of
| @isvalidwinrttype | @isvalidwinrttype
| @iswinclass | @iswinclass
| @iswininterface | @iswininterface
| @istriviallyequalitycomparable
| @isscopedenum
| @istriviallyrelocatable
; ;
new_allocated_type( new_allocated_type(
@@ -1961,7 +1968,7 @@ uuidof_bind(
int type_id: @type ref int type_id: @type ref
); );
@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; @runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof;
sizeof_bind( sizeof_bind(
unique int expr: @runtime_sizeof_or_alignof ref, unique int expr: @runtime_sizeof_or_alignof ref,

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: Add new builtin operations
compatibility: backwards

View File

@@ -1,6 +1,6 @@
/** /**
* This file provides the `bounded` predicate that is used in both `cpp/uncontrolled-arithmetic` * This file provides the `bounded` predicate that is used in `cpp/uncontrolled-arithmetic`,
* and `cpp/tainted-arithmetic`. * `cpp/tainted-arithmetic` and `cpp/uncontrolled-allocation-size`.
*/ */
private import cpp private import cpp
@@ -8,20 +8,18 @@ private import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
/** /**
* An operand `e` of a bitwise and expression `andExpr` (i.e., `andExpr` is either an `BitwiseAndExpr` * An operand `operand` of a bitwise and expression `andExpr` (i.e., `andExpr` is either a
* or an `AssignAndExpr`) with operands `operand1` and `operand2` is the operand that is not `e` is upper * `BitwiseAndExpr` or an `AssignAndExpr`) is upper bounded by some number that is less than the
* bounded by some number that is less than the maximum integer allowed by the result type of `andExpr`. * maximum integer allowed by the result type of `andExpr`.
*/ */
pragma[inline] pragma[inline]
private predicate boundedBitwiseAnd(Expr e, Expr andExpr, Expr operand1, Expr operand2) { private predicate boundedBitwiseAnd(Expr operand, Expr andExpr) {
operand1 != operand2 and upperBound(operand.getFullyConverted()) < exprMaxVal(andExpr.getFullyConverted())
e = operand1 and
upperBound(operand2.getFullyConverted()) < exprMaxVal(andExpr.getFullyConverted())
} }
/** /**
* Holds if `e` is an arithmetic expression that cannot overflow, or if `e` is an operand of an * Holds if `e` is an arithmetic expression that cannot overflow, or if `e` is an operation that
* operation that may greatly reduce the range of possible values. * may greatly reduce the range of possible values.
*/ */
predicate bounded(Expr e) { predicate bounded(Expr e) {
// There can be two separate reasons for `convertedExprMightOverflow` not holding: // There can be two separate reasons for `convertedExprMightOverflow` not holding:
@@ -35,25 +33,25 @@ predicate bounded(Expr e) {
) and ) and
not convertedExprMightOverflow(e) not convertedExprMightOverflow(e)
or or
// Optimistically assume that a remainder expression always yields a much smaller value. // Optimistically assume that the following operations always yields a much smaller value.
e = any(RemExpr rem).getLeftOperand() e instanceof RemExpr
or or
e = any(AssignRemExpr rem).getLValue() e instanceof DivExpr
or
e instanceof RShiftExpr
or or
exists(BitwiseAndExpr andExpr | exists(BitwiseAndExpr andExpr |
boundedBitwiseAnd(e, andExpr, andExpr.getAnOperand(), andExpr.getAnOperand()) e = andExpr and boundedBitwiseAnd(andExpr.getAnOperand(), andExpr)
) )
or or
exists(AssignAndExpr andExpr | // For the assignment variant of the operations we place the barrier on the assigned lvalue.
boundedBitwiseAnd(e, andExpr, andExpr.getAnOperand(), andExpr.getAnOperand()) e = any(AssignRemExpr rem).getLValue()
)
or
// Optimistically assume that a division always yields a much smaller value.
e = any(DivExpr div).getLeftOperand()
or or
e = any(AssignDivExpr div).getLValue() e = any(AssignDivExpr div).getLValue()
or or
e = any(RShiftExpr shift).getLeftOperand()
or
e = any(AssignRShiftExpr div).getLValue() e = any(AssignRShiftExpr div).getLValue()
or
exists(AssignAndExpr andExpr |
e = andExpr.getLValue() and boundedBitwiseAnd(andExpr.getRValue(), andExpr)
)
} }

View File

@@ -16,6 +16,7 @@
import cpp import cpp
import semmle.code.cpp.valuenumbering.GlobalValueNumbering import semmle.code.cpp.valuenumbering.GlobalValueNumbering
import semmle.code.cpp.controlflow.Guards import semmle.code.cpp.controlflow.Guards
import semmle.code.cpp.models.implementations.NoexceptFunction
/** Gets the `Constructor` invoked when `newExpr` allocates memory. */ /** Gets the `Constructor` invoked when `newExpr` allocates memory. */
Constructor getConstructorForAllocation(NewOrNewArrayExpr newExpr) { Constructor getConstructorForAllocation(NewOrNewArrayExpr newExpr) {
@@ -44,9 +45,8 @@ predicate deleteMayThrow(DeleteOrDeleteArrayExpr deleteExpr) {
* like it might throw an exception, and the function does not have a `noexcept` or `throw()` specifier. * like it might throw an exception, and the function does not have a `noexcept` or `throw()` specifier.
*/ */
predicate functionMayThrow(Function f) { predicate functionMayThrow(Function f) {
(not exists(f.getBlock()) or stmtMayThrow(f.getBlock())) and not f instanceof NonThrowingFunction and
not f.isNoExcept() and (not exists(f.getBlock()) or stmtMayThrow(f.getBlock()))
not f.isNoThrow()
} }
/** Holds if the evaluation of `stmt` may throw an exception. */ /** Holds if the evaluation of `stmt` may throw an exception. */
@@ -172,8 +172,7 @@ class ThrowingAllocator extends Function {
not exists(Parameter p | p = this.getAParameter() | not exists(Parameter p | p = this.getAParameter() |
p.getUnspecifiedType().stripType() instanceof NoThrowType p.getUnspecifiedType().stripType() instanceof NoThrowType
) and ) and
not this.isNoExcept() and not this instanceof NoexceptFunction
not this.isNoThrow()
) )
} }
} }

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Add modeling of C functions that don't throw, thereby increasing the precision of the `cpp/incorrect-allocation-error-handling` ("Incorrect allocation-error handling") query. The query now produces additional true positives.

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries name: codeql/cpp-queries
version: 1.2.1 version: 1.2.2-dev
groups: groups:
- cpp - cpp
- queries - queries

View File

@@ -1,4 +1,4 @@
// semmle-extractor-options: --clang --clang_version 180000 // semmle-extractor-options: --clang --edg --clang_version --edg 190000
struct S { struct S {
void f() {} void f() {}
@@ -108,3 +108,16 @@ bool b_is_unbounded_array2 = __is_unbounded_array(int[42]);
bool b_is_referenceable1 = __is_referenceable(int); bool b_is_referenceable1 = __is_referenceable(int);
bool b_is_referenceable2 = __is_referenceable(void); bool b_is_referenceable2 = __is_referenceable(void);
bool b_is_trivially_equality_comparable1 = __is_trivially_equality_comparable(int);
bool b_is_trivially_equality_comparable2 = __is_trivially_equality_comparable(void);
enum class E {
a, b
};
bool b_is_scoped_enum1 = __is_scoped_enum(E);
bool b_is_scoped_enum2 = __is_scoped_enum(int);
bool b_is_trivially_relocatable1 = __is_trivially_relocatable(int);
bool b_is_trivially_relocatable2 = __is_trivially_relocatable(void);

View File

@@ -153,7 +153,21 @@
| clang.cpp:109:28:109:50 | int | | <none> | | clang.cpp:109:28:109:50 | int | | <none> |
| clang.cpp:110:28:110:51 | __is_referenceable | void | 0 | | clang.cpp:110:28:110:51 | __is_referenceable | void | 0 |
| clang.cpp:110:28:110:51 | void | | <none> | | clang.cpp:110:28:110:51 | void | | <none> |
| clang.cpp:112:44:112:82 | __is_trivially_equality_comparable | int | 1 |
| clang.cpp:112:44:112:82 | int | | <none> |
| clang.cpp:113:44:113:83 | __is_trivially_equality_comparable | void | 0 |
| clang.cpp:113:44:113:83 | void | | <none> |
| clang.cpp:119:26:119:44 | E | | <none> |
| clang.cpp:119:26:119:44 | __is_scoped_enum | E | 1 |
| clang.cpp:120:26:120:46 | __is_scoped_enum | int | 0 |
| clang.cpp:120:26:120:46 | int | | <none> |
| clang.cpp:122:36:122:66 | __is_trivially_relocatable | int | 1 |
| clang.cpp:122:36:122:66 | int | | <none> |
| clang.cpp:123:36:123:67 | __is_trivially_relocatable | void | 0 |
| clang.cpp:123:36:123:67 | void | | <none> |
| file://:0:0:0:0 | 0 | | 0 | | file://:0:0:0:0 | 0 | | 0 |
| file://:0:0:0:0 | 0 | | 0 |
| file://:0:0:0:0 | 1 | | 1 |
| file://:0:0:0:0 | 1 | | 1 | | file://:0:0:0:0 | 1 | | 1 |
| file://:0:0:0:0 | 2 | | 2 | | file://:0:0:0:0 | 2 | | 2 |
| gcc.cpp:3:25:3:25 | 8 | | 8 | | gcc.cpp:3:25:3:25 | 8 | | 8 |

View File

@@ -848,6 +848,8 @@ edges
| simple.cpp:120:8:120:8 | *a [i] | simple.cpp:120:10:120:10 | i | provenance | | | simple.cpp:120:8:120:8 | *a [i] | simple.cpp:120:10:120:10 | i | provenance | |
| struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:14:24:14:25 | *ab [a] | provenance | | | struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:14:24:14:25 | *ab [a] | provenance | |
| struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:15:8:15:9 | *ab [a] | provenance | | | struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:15:8:15:9 | *ab [a] | provenance | |
| struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:15:8:15:9 | *ab [a] | provenance | |
| struct_init.c:15:8:15:9 | *ab [a] | struct_init.c:15:12:15:12 | a | provenance | |
| struct_init.c:15:8:15:9 | *ab [a] | struct_init.c:15:12:15:12 | a | provenance | | | struct_init.c:15:8:15:9 | *ab [a] | struct_init.c:15:12:15:12 | a | provenance | |
| struct_init.c:20:13:20:14 | *definition of ab [a] | struct_init.c:22:8:22:9 | *ab [a] | provenance | | | struct_init.c:20:13:20:14 | *definition of ab [a] | struct_init.c:22:8:22:9 | *ab [a] | provenance | |
| struct_init.c:20:13:20:14 | *definition of ab [a] | struct_init.c:24:10:24:12 | *& ... [a] | provenance | | | struct_init.c:20:13:20:14 | *definition of ab [a] | struct_init.c:24:10:24:12 | *& ... [a] | provenance | |
@@ -1758,6 +1760,8 @@ nodes
| simple.cpp:120:10:120:10 | i | semmle.label | i | | simple.cpp:120:10:120:10 | i | semmle.label | i |
| struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] | | struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] |
| struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] | | struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] |
| struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] |
| struct_init.c:15:8:15:9 | *ab [a] | semmle.label | *ab [a] |
| struct_init.c:15:8:15:9 | *ab [a] | semmle.label | *ab [a] | | struct_init.c:15:8:15:9 | *ab [a] | semmle.label | *ab [a] |
| struct_init.c:15:12:15:12 | a | semmle.label | a | | struct_init.c:15:12:15:12 | a | semmle.label | a |
| struct_init.c:20:13:20:14 | *definition of ab [a] | semmle.label | *definition of ab [a] | | struct_init.c:20:13:20:14 | *definition of ab [a] | semmle.label | *definition of ab [a] |

View File

@@ -737,6 +737,8 @@ edges
| simple.cpp:120:8:120:8 | a [i] | simple.cpp:120:10:120:10 | i | provenance | | | simple.cpp:120:8:120:8 | a [i] | simple.cpp:120:10:120:10 | i | provenance | |
| struct_init.c:14:24:14:25 | ab [a] | struct_init.c:14:24:14:25 | ab [a] | provenance | | | struct_init.c:14:24:14:25 | ab [a] | struct_init.c:14:24:14:25 | ab [a] | provenance | |
| struct_init.c:14:24:14:25 | ab [a] | struct_init.c:15:8:15:9 | ab [a] | provenance | | | struct_init.c:14:24:14:25 | ab [a] | struct_init.c:15:8:15:9 | ab [a] | provenance | |
| struct_init.c:14:24:14:25 | ab [a] | struct_init.c:15:8:15:9 | ab [a] | provenance | |
| struct_init.c:15:8:15:9 | ab [a] | struct_init.c:15:12:15:12 | a | provenance | |
| struct_init.c:15:8:15:9 | ab [a] | struct_init.c:15:12:15:12 | a | provenance | | | struct_init.c:15:8:15:9 | ab [a] | struct_init.c:15:12:15:12 | a | provenance | |
| struct_init.c:15:8:15:9 | ab [a] | struct_init.c:15:12:15:12 | a | provenance | | | struct_init.c:15:8:15:9 | ab [a] | struct_init.c:15:12:15:12 | a | provenance | |
| struct_init.c:15:8:15:9 | ab [post update] [a] | struct_init.c:14:24:14:25 | ab [a] | provenance | | | struct_init.c:15:8:15:9 | ab [post update] [a] | struct_init.c:14:24:14:25 | ab [a] | provenance | |
@@ -1549,6 +1551,8 @@ nodes
| simple.cpp:120:10:120:10 | i | semmle.label | i | | simple.cpp:120:10:120:10 | i | semmle.label | i |
| struct_init.c:14:24:14:25 | ab [a] | semmle.label | ab [a] | | struct_init.c:14:24:14:25 | ab [a] | semmle.label | ab [a] |
| struct_init.c:14:24:14:25 | ab [a] | semmle.label | ab [a] | | struct_init.c:14:24:14:25 | ab [a] | semmle.label | ab [a] |
| struct_init.c:14:24:14:25 | ab [a] | semmle.label | ab [a] |
| struct_init.c:15:8:15:9 | ab [a] | semmle.label | ab [a] |
| struct_init.c:15:8:15:9 | ab [a] | semmle.label | ab [a] | | struct_init.c:15:8:15:9 | ab [a] | semmle.label | ab [a] |
| struct_init.c:15:8:15:9 | ab [post update] [a] | semmle.label | ab [post update] [a] | | struct_init.c:15:8:15:9 | ab [post update] [a] | semmle.label | ab [post update] [a] |
| struct_init.c:15:12:15:12 | a | semmle.label | a | | struct_init.c:15:12:15:12 | a | semmle.label | a |

View File

@@ -450,7 +450,7 @@ void test_qualifiers()
b.member = source(); b.member = source();
sink(b); // $ ir MISSING: ast sink(b); // $ ir MISSING: ast
sink(b.member); // $ ast,ir sink(b.member); // $ ast,ir
sink(b.getMember()); // $ ir MISSING: ast sink(b.getMember()); // $ MISSING: ir ast
c = new MyClass2(0); c = new MyClass2(0);

View File

@@ -115,8 +115,8 @@ void test_vector_swap() {
v3.swap(v4); v3.swap(v4);
sink(v1); sink(v1);
sink(v2); // $ ir MISSING:ast sink(v2); // $ MISSING:ir ast
sink(v3); // $ ir MISSING:ast sink(v3); // $ MISSING:ir ast
sink(v4); sink(v4);
} }

View File

@@ -0,0 +1,30 @@
// semmle-extractor-options: --clang --edg --clang_version --edg 190000
typedef unsigned int size_t;
class MyClass
{
public:
int x;
int *ptr;
char c;
};
void func() {
int i;
char c;
int * ptr;
MyClass mc;
int arr[10];
size_t sz1 = __datasizeof(int);
size_t sz2 = __datasizeof(char);
size_t sz3 = __datasizeof(int *);
size_t sz4 = __datasizeof(MyClass);
size_t sz5 = __datasizeof(i);
size_t sz6 = __datasizeof(c);
size_t sz7 = __datasizeof(ptr);
size_t sz8 = __datasizeof(mc);
size_t sz9 = __datasizeof(arr);
size_t sz10 = __datasizeof(arr[4]);
}

View File

@@ -0,0 +1,10 @@
| datasizeof.cpp:20:15:20:31 | __datasizeof(int) | 4 | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int |
| datasizeof.cpp:21:15:21:32 | __datasizeof(char) | 1 | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | char |
| datasizeof.cpp:22:15:22:33 | __datasizeof(int *) | 8 | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int * |
| datasizeof.cpp:23:15:23:35 | __datasizeof(MyClass) | 24 | DatasizeofTypeOperator.getTypeOperand() | datasizeof.cpp:5:7:5:13 | MyClass |
| datasizeof.cpp:24:15:24:29 | __datasizeof(<expr>) | 4 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:24:28:24:28 | i |
| datasizeof.cpp:25:15:25:29 | __datasizeof(<expr>) | 1 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:25:28:25:28 | c |
| datasizeof.cpp:26:15:26:31 | __datasizeof(<expr>) | 8 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:26:28:26:30 | ptr |
| datasizeof.cpp:27:15:27:30 | __datasizeof(<expr>) | 24 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:27:28:27:29 | mc |
| datasizeof.cpp:28:15:28:31 | __datasizeof(<expr>) | 40 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:28:28:28:30 | arr |
| datasizeof.cpp:29:16:29:35 | __datasizeof(<expr>) | 4 | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:29:29:29:34 | access to array |

View File

@@ -0,0 +1,10 @@
import cpp
from DatasizeofOperator sto, string elemDesc, Element e
where
elemDesc = "DatasizeofTypeOperator.getTypeOperand()" and
e = sto.(DatasizeofTypeOperator).getTypeOperand()
or
elemDesc = "DatasizeofExprOperator.getExprOperand()" and
e = sto.(DatasizeofExprOperator).getExprOperand()
select sto, sto.getValue(), elemDesc, e

View File

@@ -1,10 +1,10 @@
| sizeof.cpp:19:15:19:25 | sizeof(int) | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int | | sizeof.cpp:19:15:19:25 | sizeof(int) | 4 | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int |
| sizeof.cpp:20:15:20:26 | sizeof(char) | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | char | | sizeof.cpp:20:15:20:26 | sizeof(char) | 1 | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | char |
| sizeof.cpp:21:15:21:27 | sizeof(int *) | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int * | | sizeof.cpp:21:15:21:27 | sizeof(int *) | 8 | SizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int * |
| sizeof.cpp:22:15:22:29 | sizeof(MyClass) | SizeofTypeOperator.getTypeOperand() | sizeof.cpp:4:7:4:13 | MyClass | | sizeof.cpp:22:15:22:29 | sizeof(MyClass) | 16 | SizeofTypeOperator.getTypeOperand() | sizeof.cpp:4:7:4:13 | MyClass |
| sizeof.cpp:23:15:23:23 | sizeof(<expr>) | SizeofExprOperator.getExprOperand() | sizeof.cpp:23:22:23:22 | i | | sizeof.cpp:23:15:23:23 | sizeof(<expr>) | 4 | SizeofExprOperator.getExprOperand() | sizeof.cpp:23:22:23:22 | i |
| sizeof.cpp:24:15:24:23 | sizeof(<expr>) | SizeofExprOperator.getExprOperand() | sizeof.cpp:24:22:24:22 | c | | sizeof.cpp:24:15:24:23 | sizeof(<expr>) | 1 | SizeofExprOperator.getExprOperand() | sizeof.cpp:24:22:24:22 | c |
| sizeof.cpp:25:15:25:25 | sizeof(<expr>) | SizeofExprOperator.getExprOperand() | sizeof.cpp:25:22:25:24 | ptr | | sizeof.cpp:25:15:25:25 | sizeof(<expr>) | 8 | SizeofExprOperator.getExprOperand() | sizeof.cpp:25:22:25:24 | ptr |
| sizeof.cpp:26:15:26:24 | sizeof(<expr>) | SizeofExprOperator.getExprOperand() | sizeof.cpp:26:22:26:23 | mc | | sizeof.cpp:26:15:26:24 | sizeof(<expr>) | 16 | SizeofExprOperator.getExprOperand() | sizeof.cpp:26:22:26:23 | mc |
| sizeof.cpp:27:15:27:25 | sizeof(<expr>) | SizeofExprOperator.getExprOperand() | sizeof.cpp:27:22:27:24 | arr | | sizeof.cpp:27:15:27:25 | sizeof(<expr>) | 40 | SizeofExprOperator.getExprOperand() | sizeof.cpp:27:22:27:24 | arr |
| sizeof.cpp:28:16:28:29 | sizeof(<expr>) | SizeofExprOperator.getExprOperand() | sizeof.cpp:28:23:28:28 | access to array | | sizeof.cpp:28:16:28:29 | sizeof(<expr>) | 4 | SizeofExprOperator.getExprOperand() | sizeof.cpp:28:23:28:28 | access to array |

View File

@@ -7,4 +7,4 @@ where
or or
elemDesc = "SizeofExprOperator.getExprOperand()" and elemDesc = "SizeofExprOperator.getExprOperand()" and
e = sto.(SizeofExprOperator).getExprOperand() e = sto.(SizeofExprOperator).getExprOperand()
select sto, elemDesc, e select sto, sto.getValue(), elemDesc, e

View File

@@ -16,7 +16,6 @@ edges
| test_free.cpp:152:27:152:27 | pointer to free output argument | test_free.cpp:153:5:153:5 | a | provenance | | | test_free.cpp:152:27:152:27 | pointer to free output argument | test_free.cpp:153:5:153:5 | a | provenance | |
| test_free.cpp:233:14:233:15 | pointer to free output argument | test_free.cpp:234:9:234:11 | *... ++ | provenance | | | test_free.cpp:233:14:233:15 | pointer to free output argument | test_free.cpp:234:9:234:11 | *... ++ | provenance | |
| test_free.cpp:234:9:234:11 | *... ++ | test_free.cpp:236:9:236:10 | * ... | provenance | | | test_free.cpp:234:9:234:11 | *... ++ | test_free.cpp:236:9:236:10 | * ... | provenance | |
| test_free.cpp:238:15:238:17 | *... ++ | test_free.cpp:238:15:238:17 | *... ++ | provenance | |
| test_free.cpp:238:15:238:17 | *... ++ | test_free.cpp:241:9:241:10 | * ... | provenance | | | test_free.cpp:238:15:238:17 | *... ++ | test_free.cpp:241:9:241:10 | * ... | provenance | |
| test_free.cpp:239:14:239:15 | pointer to free output argument | test_free.cpp:238:15:238:17 | *... ++ | provenance | | | test_free.cpp:239:14:239:15 | pointer to free output argument | test_free.cpp:238:15:238:17 | *... ++ | provenance | |
| test_free.cpp:245:10:245:11 | pointer to free output argument | test_free.cpp:246:9:246:10 | * ... | provenance | | | test_free.cpp:245:10:245:11 | pointer to free output argument | test_free.cpp:246:9:246:10 | * ... | provenance | |

View File

@@ -32,6 +32,8 @@ edges
| test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r | provenance | | | test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r | provenance | |
| test.cpp:30:13:30:14 | get_rand2 output argument | test.cpp:31:7:31:7 | r | provenance | | | test.cpp:30:13:30:14 | get_rand2 output argument | test.cpp:31:7:31:7 | r | provenance | |
| test.cpp:36:13:36:13 | get_rand3 output argument | test.cpp:37:7:37:7 | r | provenance | | | test.cpp:36:13:36:13 | get_rand3 output argument | test.cpp:37:7:37:7 | r | provenance | |
| test.cpp:62:19:62:24 | call to rand | test.cpp:62:19:62:24 | call to rand | provenance | |
| test.cpp:62:19:62:24 | call to rand | test.cpp:65:9:65:9 | x | provenance | |
| test.cpp:86:10:86:13 | call to rand | test.cpp:86:10:86:13 | call to rand | provenance | | | test.cpp:86:10:86:13 | call to rand | test.cpp:86:10:86:13 | call to rand | provenance | |
| test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x | provenance | | | test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x | provenance | |
| test.cpp:98:10:98:13 | call to rand | test.cpp:98:10:98:13 | call to rand | provenance | | | test.cpp:98:10:98:13 | call to rand | test.cpp:98:10:98:13 | call to rand | provenance | |
@@ -105,6 +107,9 @@ nodes
| test.cpp:31:7:31:7 | r | semmle.label | r | | test.cpp:31:7:31:7 | r | semmle.label | r |
| test.cpp:36:13:36:13 | get_rand3 output argument | semmle.label | get_rand3 output argument | | test.cpp:36:13:36:13 | get_rand3 output argument | semmle.label | get_rand3 output argument |
| test.cpp:37:7:37:7 | r | semmle.label | r | | test.cpp:37:7:37:7 | r | semmle.label | r |
| test.cpp:62:19:62:24 | call to rand | semmle.label | call to rand |
| test.cpp:62:19:62:24 | call to rand | semmle.label | call to rand |
| test.cpp:65:9:65:9 | x | semmle.label | x |
| test.cpp:86:10:86:13 | call to rand | semmle.label | call to rand | | test.cpp:86:10:86:13 | call to rand | semmle.label | call to rand |
| test.cpp:86:10:86:13 | call to rand | semmle.label | call to rand | | test.cpp:86:10:86:13 | call to rand | semmle.label | call to rand |
| test.cpp:90:10:90:10 | x | semmle.label | x | | test.cpp:90:10:90:10 | x | semmle.label | x |
@@ -156,6 +161,7 @@ subpaths
| test.cpp:25:7:25:7 | r | test.cpp:8:9:8:12 | call to rand | test.cpp:25:7:25:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:8:9:8:12 | call to rand | uncontrolled value | | test.cpp:25:7:25:7 | r | test.cpp:8:9:8:12 | call to rand | test.cpp:25:7:25:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:8:9:8:12 | call to rand | uncontrolled value |
| test.cpp:31:7:31:7 | r | test.cpp:13:10:13:13 | call to rand | test.cpp:31:7:31:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:13:10:13:13 | call to rand | uncontrolled value | | test.cpp:31:7:31:7 | r | test.cpp:13:10:13:13 | call to rand | test.cpp:31:7:31:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:13:10:13:13 | call to rand | uncontrolled value |
| test.cpp:37:7:37:7 | r | test.cpp:18:9:18:12 | call to rand | test.cpp:37:7:37:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:18:9:18:12 | call to rand | uncontrolled value | | test.cpp:37:7:37:7 | r | test.cpp:18:9:18:12 | call to rand | test.cpp:37:7:37:7 | r | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:18:9:18:12 | call to rand | uncontrolled value |
| test.cpp:65:9:65:9 | x | test.cpp:62:19:62:24 | call to rand | test.cpp:65:9:65:9 | x | This arithmetic expression depends on an $@, potentially causing an underflow. | test.cpp:62:19:62:22 | call to rand | uncontrolled value |
| test.cpp:90:10:90:10 | x | test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:86:10:86:13 | call to rand | uncontrolled value | | test.cpp:90:10:90:10 | x | test.cpp:86:10:86:13 | call to rand | test.cpp:90:10:90:10 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:86:10:86:13 | call to rand | uncontrolled value |
| test.cpp:102:10:102:10 | x | test.cpp:98:10:98:13 | call to rand | test.cpp:102:10:102:10 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:98:10:98:13 | call to rand | uncontrolled value | | test.cpp:102:10:102:10 | x | test.cpp:98:10:98:13 | call to rand | test.cpp:102:10:102:10 | x | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:98:10:98:13 | call to rand | uncontrolled value |
| test.cpp:146:9:146:9 | y | test.cpp:137:10:137:13 | call to rand | test.cpp:146:9:146:9 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:137:10:137:13 | call to rand | uncontrolled value | | test.cpp:146:9:146:9 | y | test.cpp:137:10:137:13 | call to rand | test.cpp:146:9:146:9 | y | This arithmetic expression depends on an $@, potentially causing an overflow. | test.cpp:137:10:137:13 | call to rand | uncontrolled value |

View File

@@ -62,7 +62,7 @@ unsigned int test_remainder_subtract_unsigned()
unsigned int x = rand(); unsigned int x = rand();
unsigned int y = x % 100; // y <= x unsigned int y = x % 100; // y <= x
return x - y; // GOOD (as y <= x) return x - y; // GOOD (as y <= x) [FALSE POSITIVE]
} }
typedef unsigned long size_t; typedef unsigned long size_t;

View File

@@ -13,26 +13,30 @@ edges
| test.cpp:133:19:133:32 | *call to getenv | test.cpp:133:14:133:17 | call to atoi | provenance | TaintFunction | | test.cpp:133:19:133:32 | *call to getenv | test.cpp:133:14:133:17 | call to atoi | provenance | TaintFunction |
| test.cpp:148:15:148:18 | call to atol | test.cpp:152:11:152:28 | ... * ... | provenance | | | test.cpp:148:15:148:18 | call to atol | test.cpp:152:11:152:28 | ... * ... | provenance | |
| test.cpp:148:20:148:33 | *call to getenv | test.cpp:148:15:148:18 | call to atol | provenance | TaintFunction | | test.cpp:148:20:148:33 | *call to getenv | test.cpp:148:15:148:18 | call to atol | provenance | TaintFunction |
| test.cpp:224:8:224:23 | *get_tainted_size | test.cpp:256:9:256:24 | call to get_tainted_size | provenance | | | test.cpp:190:14:190:17 | call to atoi | test.cpp:194:11:194:28 | ... * ... | provenance | |
| test.cpp:226:9:226:42 | ... * ... | test.cpp:224:8:224:23 | *get_tainted_size | provenance | | | test.cpp:190:19:190:32 | *call to getenv | test.cpp:190:14:190:17 | call to atoi | provenance | TaintFunction |
| test.cpp:226:14:226:27 | *call to getenv | test.cpp:226:9:226:42 | ... * ... | provenance | TaintFunction | | test.cpp:205:14:205:17 | call to atoi | test.cpp:209:11:209:28 | ... * ... | provenance | |
| test.cpp:245:21:245:21 | s | test.cpp:246:21:246:21 | s | provenance | | | test.cpp:205:19:205:32 | *call to getenv | test.cpp:205:14:205:17 | call to atoi | provenance | TaintFunction |
| test.cpp:252:19:252:52 | ... * ... | test.cpp:254:9:254:18 | local_size | provenance | | | test.cpp:239:8:239:23 | *get_tainted_size | test.cpp:271:9:271:24 | call to get_tainted_size | provenance | |
| test.cpp:252:19:252:52 | ... * ... | test.cpp:260:11:260:20 | local_size | provenance | | | test.cpp:241:9:241:42 | ... * ... | test.cpp:239:8:239:23 | *get_tainted_size | provenance | |
| test.cpp:252:19:252:52 | ... * ... | test.cpp:262:10:262:19 | local_size | provenance | | | test.cpp:241:14:241:27 | *call to getenv | test.cpp:241:9:241:42 | ... * ... | provenance | TaintFunction |
| test.cpp:252:24:252:37 | *call to getenv | test.cpp:252:19:252:52 | ... * ... | provenance | TaintFunction | | test.cpp:260:21:260:21 | s | test.cpp:261:21:261:21 | s | provenance | |
| test.cpp:262:10:262:19 | local_size | test.cpp:245:21:245:21 | s | provenance | | | test.cpp:267:19:267:52 | ... * ... | test.cpp:269:9:269:18 | local_size | provenance | |
| test.cpp:265:20:265:27 | *out_size | test.cpp:304:17:304:20 | get_size output argument | provenance | | | test.cpp:267:19:267:52 | ... * ... | test.cpp:275:11:275:20 | local_size | provenance | |
| test.cpp:265:20:265:27 | *out_size | test.cpp:320:18:320:21 | get_size output argument | provenance | | | test.cpp:267:19:267:52 | ... * ... | test.cpp:277:10:277:19 | local_size | provenance | |
| test.cpp:266:2:266:32 | ... = ... | test.cpp:265:20:265:27 | *out_size | provenance | | | test.cpp:267:24:267:37 | *call to getenv | test.cpp:267:19:267:52 | ... * ... | provenance | TaintFunction |
| test.cpp:266:18:266:31 | *call to getenv | test.cpp:266:2:266:32 | ... = ... | provenance | TaintFunction | | test.cpp:277:10:277:19 | local_size | test.cpp:260:21:260:21 | s | provenance | |
| test.cpp:274:15:274:18 | call to atoi | test.cpp:278:11:278:29 | ... * ... | provenance | | | test.cpp:280:20:280:27 | *out_size | test.cpp:319:17:319:20 | get_size output argument | provenance | |
| test.cpp:274:20:274:33 | *call to getenv | test.cpp:274:15:274:18 | call to atoi | provenance | TaintFunction | | test.cpp:280:20:280:27 | *out_size | test.cpp:335:18:335:21 | get_size output argument | provenance | |
| test.cpp:304:17:304:20 | get_size output argument | test.cpp:306:11:306:28 | ... * ... | provenance | | | test.cpp:281:2:281:32 | ... = ... | test.cpp:280:20:280:27 | *out_size | provenance | |
| test.cpp:320:18:320:21 | get_size output argument | test.cpp:323:10:323:27 | ... * ... | provenance | | | test.cpp:281:18:281:31 | *call to getenv | test.cpp:281:2:281:32 | ... = ... | provenance | TaintFunction |
| test.cpp:368:13:368:16 | call to atoi | test.cpp:370:35:370:38 | size | provenance | | | test.cpp:289:15:289:18 | call to atoi | test.cpp:293:11:293:29 | ... * ... | provenance | |
| test.cpp:368:13:368:16 | call to atoi | test.cpp:371:35:371:38 | size | provenance | | | test.cpp:289:20:289:33 | *call to getenv | test.cpp:289:15:289:18 | call to atoi | provenance | TaintFunction |
| test.cpp:368:18:368:31 | *call to getenv | test.cpp:368:13:368:16 | call to atoi | provenance | TaintFunction | | test.cpp:319:17:319:20 | get_size output argument | test.cpp:321:11:321:28 | ... * ... | provenance | |
| test.cpp:335:18:335:21 | get_size output argument | test.cpp:338:10:338:27 | ... * ... | provenance | |
| test.cpp:383:13:383:16 | call to atoi | test.cpp:385:35:385:38 | size | provenance | |
| test.cpp:383:13:383:16 | call to atoi | test.cpp:386:35:386:38 | size | provenance | |
| test.cpp:383:18:383:31 | *call to getenv | test.cpp:383:13:383:16 | call to atoi | provenance | TaintFunction |
nodes nodes
| test.cpp:39:27:39:30 | **argv | semmle.label | **argv | | test.cpp:39:27:39:30 | **argv | semmle.label | **argv |
| test.cpp:40:16:40:19 | call to atoi | semmle.label | call to atoi | | test.cpp:40:16:40:19 | call to atoi | semmle.label | call to atoi |
@@ -52,31 +56,37 @@ nodes
| test.cpp:148:15:148:18 | call to atol | semmle.label | call to atol | | test.cpp:148:15:148:18 | call to atol | semmle.label | call to atol |
| test.cpp:148:20:148:33 | *call to getenv | semmle.label | *call to getenv | | test.cpp:148:20:148:33 | *call to getenv | semmle.label | *call to getenv |
| test.cpp:152:11:152:28 | ... * ... | semmle.label | ... * ... | | test.cpp:152:11:152:28 | ... * ... | semmle.label | ... * ... |
| test.cpp:224:8:224:23 | *get_tainted_size | semmle.label | *get_tainted_size | | test.cpp:190:14:190:17 | call to atoi | semmle.label | call to atoi |
| test.cpp:226:9:226:42 | ... * ... | semmle.label | ... * ... | | test.cpp:190:19:190:32 | *call to getenv | semmle.label | *call to getenv |
| test.cpp:226:14:226:27 | *call to getenv | semmle.label | *call to getenv | | test.cpp:194:11:194:28 | ... * ... | semmle.label | ... * ... |
| test.cpp:245:21:245:21 | s | semmle.label | s | | test.cpp:205:14:205:17 | call to atoi | semmle.label | call to atoi |
| test.cpp:246:21:246:21 | s | semmle.label | s | | test.cpp:205:19:205:32 | *call to getenv | semmle.label | *call to getenv |
| test.cpp:252:19:252:52 | ... * ... | semmle.label | ... * ... | | test.cpp:209:11:209:28 | ... * ... | semmle.label | ... * ... |
| test.cpp:252:24:252:37 | *call to getenv | semmle.label | *call to getenv | | test.cpp:239:8:239:23 | *get_tainted_size | semmle.label | *get_tainted_size |
| test.cpp:254:9:254:18 | local_size | semmle.label | local_size | | test.cpp:241:9:241:42 | ... * ... | semmle.label | ... * ... |
| test.cpp:256:9:256:24 | call to get_tainted_size | semmle.label | call to get_tainted_size | | test.cpp:241:14:241:27 | *call to getenv | semmle.label | *call to getenv |
| test.cpp:260:11:260:20 | local_size | semmle.label | local_size | | test.cpp:260:21:260:21 | s | semmle.label | s |
| test.cpp:262:10:262:19 | local_size | semmle.label | local_size | | test.cpp:261:21:261:21 | s | semmle.label | s |
| test.cpp:265:20:265:27 | *out_size | semmle.label | *out_size | | test.cpp:267:19:267:52 | ... * ... | semmle.label | ... * ... |
| test.cpp:266:2:266:32 | ... = ... | semmle.label | ... = ... | | test.cpp:267:24:267:37 | *call to getenv | semmle.label | *call to getenv |
| test.cpp:266:18:266:31 | *call to getenv | semmle.label | *call to getenv | | test.cpp:269:9:269:18 | local_size | semmle.label | local_size |
| test.cpp:274:15:274:18 | call to atoi | semmle.label | call to atoi | | test.cpp:271:9:271:24 | call to get_tainted_size | semmle.label | call to get_tainted_size |
| test.cpp:274:20:274:33 | *call to getenv | semmle.label | *call to getenv | | test.cpp:275:11:275:20 | local_size | semmle.label | local_size |
| test.cpp:278:11:278:29 | ... * ... | semmle.label | ... * ... | | test.cpp:277:10:277:19 | local_size | semmle.label | local_size |
| test.cpp:304:17:304:20 | get_size output argument | semmle.label | get_size output argument | | test.cpp:280:20:280:27 | *out_size | semmle.label | *out_size |
| test.cpp:306:11:306:28 | ... * ... | semmle.label | ... * ... | | test.cpp:281:2:281:32 | ... = ... | semmle.label | ... = ... |
| test.cpp:320:18:320:21 | get_size output argument | semmle.label | get_size output argument | | test.cpp:281:18:281:31 | *call to getenv | semmle.label | *call to getenv |
| test.cpp:323:10:323:27 | ... * ... | semmle.label | ... * ... | | test.cpp:289:15:289:18 | call to atoi | semmle.label | call to atoi |
| test.cpp:368:13:368:16 | call to atoi | semmle.label | call to atoi | | test.cpp:289:20:289:33 | *call to getenv | semmle.label | *call to getenv |
| test.cpp:368:18:368:31 | *call to getenv | semmle.label | *call to getenv | | test.cpp:293:11:293:29 | ... * ... | semmle.label | ... * ... |
| test.cpp:370:35:370:38 | size | semmle.label | size | | test.cpp:319:17:319:20 | get_size output argument | semmle.label | get_size output argument |
| test.cpp:371:35:371:38 | size | semmle.label | size | | test.cpp:321:11:321:28 | ... * ... | semmle.label | ... * ... |
| test.cpp:335:18:335:21 | get_size output argument | semmle.label | get_size output argument |
| test.cpp:338:10:338:27 | ... * ... | semmle.label | ... * ... |
| test.cpp:383:13:383:16 | call to atoi | semmle.label | call to atoi |
| test.cpp:383:18:383:31 | *call to getenv | semmle.label | *call to getenv |
| test.cpp:385:35:385:38 | size | semmle.label | size |
| test.cpp:386:35:386:38 | size | semmle.label | size |
subpaths subpaths
#select #select
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:27:39:30 | **argv | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:39:27:39:30 | **argv | user input (a command-line argument) | | test.cpp:43:31:43:36 | call to malloc | test.cpp:39:27:39:30 | **argv | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:39:27:39:30 | **argv | user input (a command-line argument) |
@@ -88,12 +98,14 @@ subpaths
| test.cpp:128:17:128:22 | call to malloc | test.cpp:124:18:124:31 | *call to getenv | test.cpp:128:24:128:41 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:124:18:124:31 | *call to getenv | user input (an environment variable) | | test.cpp:128:17:128:22 | call to malloc | test.cpp:124:18:124:31 | *call to getenv | test.cpp:128:24:128:41 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:124:18:124:31 | *call to getenv | user input (an environment variable) |
| test.cpp:135:3:135:8 | call to malloc | test.cpp:133:19:133:32 | *call to getenv | test.cpp:135:10:135:27 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:133:19:133:32 | *call to getenv | user input (an environment variable) | | test.cpp:135:3:135:8 | call to malloc | test.cpp:133:19:133:32 | *call to getenv | test.cpp:135:10:135:27 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:133:19:133:32 | *call to getenv | user input (an environment variable) |
| test.cpp:152:4:152:9 | call to malloc | test.cpp:148:20:148:33 | *call to getenv | test.cpp:152:11:152:28 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:148:20:148:33 | *call to getenv | user input (an environment variable) | | test.cpp:152:4:152:9 | call to malloc | test.cpp:148:20:148:33 | *call to getenv | test.cpp:152:11:152:28 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:148:20:148:33 | *call to getenv | user input (an environment variable) |
| test.cpp:246:14:246:19 | call to malloc | test.cpp:252:24:252:37 | *call to getenv | test.cpp:246:21:246:21 | s | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:252:24:252:37 | *call to getenv | user input (an environment variable) | | test.cpp:194:4:194:9 | call to malloc | test.cpp:190:19:190:32 | *call to getenv | test.cpp:194:11:194:28 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:190:19:190:32 | *call to getenv | user input (an environment variable) |
| test.cpp:254:2:254:7 | call to malloc | test.cpp:252:24:252:37 | *call to getenv | test.cpp:254:9:254:18 | local_size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:252:24:252:37 | *call to getenv | user input (an environment variable) | | test.cpp:209:4:209:9 | call to malloc | test.cpp:205:19:205:32 | *call to getenv | test.cpp:209:11:209:28 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:205:19:205:32 | *call to getenv | user input (an environment variable) |
| test.cpp:256:2:256:7 | call to malloc | test.cpp:226:14:226:27 | *call to getenv | test.cpp:256:9:256:24 | call to get_tainted_size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:226:14:226:27 | *call to getenv | user input (an environment variable) | | test.cpp:261:14:261:19 | call to malloc | test.cpp:267:24:267:37 | *call to getenv | test.cpp:261:21:261:21 | s | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:267:24:267:37 | *call to getenv | user input (an environment variable) |
| test.cpp:260:2:260:9 | call to my_alloc | test.cpp:252:24:252:37 | *call to getenv | test.cpp:260:11:260:20 | local_size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:252:24:252:37 | *call to getenv | user input (an environment variable) | | test.cpp:269:2:269:7 | call to malloc | test.cpp:267:24:267:37 | *call to getenv | test.cpp:269:9:269:18 | local_size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:267:24:267:37 | *call to getenv | user input (an environment variable) |
| test.cpp:278:4:278:9 | call to malloc | test.cpp:274:20:274:33 | *call to getenv | test.cpp:278:11:278:29 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:274:20:274:33 | *call to getenv | user input (an environment variable) | | test.cpp:271:2:271:7 | call to malloc | test.cpp:241:14:241:27 | *call to getenv | test.cpp:271:9:271:24 | call to get_tainted_size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:241:14:241:27 | *call to getenv | user input (an environment variable) |
| test.cpp:306:4:306:9 | call to malloc | test.cpp:266:18:266:31 | *call to getenv | test.cpp:306:11:306:28 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:266:18:266:31 | *call to getenv | user input (an environment variable) | | test.cpp:275:2:275:9 | call to my_alloc | test.cpp:267:24:267:37 | *call to getenv | test.cpp:275:11:275:20 | local_size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:267:24:267:37 | *call to getenv | user input (an environment variable) |
| test.cpp:323:3:323:8 | call to malloc | test.cpp:266:18:266:31 | *call to getenv | test.cpp:323:10:323:27 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:266:18:266:31 | *call to getenv | user input (an environment variable) | | test.cpp:293:4:293:9 | call to malloc | test.cpp:289:20:289:33 | *call to getenv | test.cpp:293:11:293:29 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:289:20:289:33 | *call to getenv | user input (an environment variable) |
| test.cpp:370:25:370:33 | call to MyMalloc1 | test.cpp:368:18:368:31 | *call to getenv | test.cpp:370:35:370:38 | size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:368:18:368:31 | *call to getenv | user input (an environment variable) | | test.cpp:321:4:321:9 | call to malloc | test.cpp:281:18:281:31 | *call to getenv | test.cpp:321:11:321:28 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:281:18:281:31 | *call to getenv | user input (an environment variable) |
| test.cpp:371:25:371:33 | call to MyMalloc2 | test.cpp:368:18:368:31 | *call to getenv | test.cpp:371:35:371:38 | size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:368:18:368:31 | *call to getenv | user input (an environment variable) | | test.cpp:338:3:338:8 | call to malloc | test.cpp:281:18:281:31 | *call to getenv | test.cpp:338:10:338:27 | ... * ... | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:281:18:281:31 | *call to getenv | user input (an environment variable) |
| test.cpp:385:25:385:33 | call to MyMalloc1 | test.cpp:383:18:383:31 | *call to getenv | test.cpp:385:35:385:38 | size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:383:18:383:31 | *call to getenv | user input (an environment variable) |
| test.cpp:386:25:386:33 | call to MyMalloc2 | test.cpp:383:18:383:31 | *call to getenv | test.cpp:386:35:386:38 | size | This allocation size is derived from $@ and could allocate arbitrary amounts of memory. | test.cpp:383:18:383:31 | *call to getenv | user input (an environment variable) |

View File

@@ -191,7 +191,22 @@ void more_bounded_tests() {
if (size % 100) if (size % 100)
{ {
malloc(size * sizeof(int)); // BAD [NOT DETECTED] malloc(size * sizeof(int)); // BAD
}
}
{
int size = atoi(getenv("USER"));
int size2 = size & 7; // Pick the first three bits of size
malloc(size2 * sizeof(int)); // GOOD
}
{
int size = atoi(getenv("USER"));
if (size & 7)
{
malloc(size * sizeof(int)); // BAD
} }
} }

View File

@@ -22,11 +22,9 @@ edges
| test.c:41:5:41:24 | ... = ... | test.c:44:7:44:10 | len2 | provenance | | | test.c:41:5:41:24 | ... = ... | test.c:44:7:44:10 | len2 | provenance | |
| test.c:41:5:41:24 | ... = ... | test.c:44:7:44:12 | ... -- | provenance | | | test.c:41:5:41:24 | ... = ... | test.c:44:7:44:12 | ... -- | provenance | |
| test.c:44:7:44:12 | ... -- | test.c:44:7:44:10 | len2 | provenance | | | test.c:44:7:44:12 | ... -- | test.c:44:7:44:10 | len2 | provenance | |
| test.c:44:7:44:12 | ... -- | test.c:44:7:44:12 | ... -- | provenance | |
| test.c:51:5:51:24 | ... = ... | test.c:54:7:54:10 | len3 | provenance | | | test.c:51:5:51:24 | ... = ... | test.c:54:7:54:10 | len3 | provenance | |
| test.c:51:5:51:24 | ... = ... | test.c:54:7:54:12 | ... -- | provenance | | | test.c:51:5:51:24 | ... = ... | test.c:54:7:54:12 | ... -- | provenance | |
| test.c:54:7:54:12 | ... -- | test.c:54:7:54:10 | len3 | provenance | | | test.c:54:7:54:12 | ... -- | test.c:54:7:54:10 | len3 | provenance | |
| test.c:54:7:54:12 | ... -- | test.c:54:7:54:12 | ... -- | provenance | |
nodes nodes
| test2.cpp:12:21:12:21 | v | semmle.label | v | | 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 |

View File

@@ -2,25 +2,25 @@
| test.cpp:43:2:45:2 | for(...;...;...) ... | test.cpp:43:18:43:26 | ... < ... | | i | { ... } | i | ExprStmt | | test.cpp:43:2:45:2 | for(...;...;...) ... | test.cpp:43:18:43:26 | ... < ... | | i | { ... } | i | ExprStmt |
| test.cpp:74:2:77:2 | while (...) ... | test.cpp:74:9:74:17 | ... > ... | 1 | count | { ... } | count | ExprStmt | | test.cpp:74:2:77:2 | while (...) ... | test.cpp:74:9:74:17 | ... > ... | 1 | count | { ... } | count | ExprStmt |
| test.cpp:84:2:88:2 | while (...) ... | test.cpp:84:9:84:17 | ... > ... | | count | { ... } | count | if (...) ... | | test.cpp:84:2:88:2 | while (...) ... | test.cpp:84:9:84:17 | ... > ... | | count | { ... } | count | if (...) ... |
| test.cpp:171:3:173:3 | while (...) ... | test.cpp:171:10:171:43 | ... != ... | 0 | | { ... } | 0 | return ... | | test.cpp:172:3:174:3 | while (...) ... | test.cpp:172:10:172:43 | ... != ... | | args | { ... } | args | return ... |
| test.cpp:251:2:255:2 | while (...) ... | test.cpp:251:9:251:12 | loop | 1 | loop | { ... } | loop | return ... | | test.cpp:259:2:263:2 | while (...) ... | test.cpp:259:9:259:12 | loop | 1 | loop | { ... } | loop | return ... |
| test.cpp:263:2:267:2 | while (...) ... | test.cpp:263:9:263:20 | ... && ... | 1 | 1 | { ... } | ... && ... | return ... | | test.cpp:271:2:275:2 | while (...) ... | test.cpp:271:9:271:20 | ... && ... | 1 | 1 | { ... } | ... && ... | return ... |
| test.cpp:275:2:279:2 | while (...) ... | test.cpp:275:9:275:13 | ! ... | 1 | stop | { ... } | stop | return ... | | test.cpp:283:2:287:2 | while (...) ... | test.cpp:283:9:283:13 | ! ... | 1 | stop | { ... } | stop | return ... |
| test.cpp:287:2:291:2 | while (...) ... | test.cpp:287:9:287:20 | ... && ... | 1 | loop | { ... } | loop | return ... | | test.cpp:295:2:299:2 | while (...) ... | test.cpp:295:9:295:20 | ... && ... | 1 | loop | { ... } | loop | return ... |
| test.cpp:299:2:303:2 | while (...) ... | test.cpp:299:9:299:20 | ... && ... | 1 | loop | { ... } | ... && ..., loop | return ... | | test.cpp:307:2:311:2 | while (...) ... | test.cpp:307:9:307:20 | ... && ... | 1 | loop | { ... } | ... && ..., loop | return ... |
| test.cpp:311:2:315:2 | while (...) ... | test.cpp:311:9:311:21 | ... \|\| ... | 1 | ... \|\| ... | { ... } | 0 | return ... | | test.cpp:319:2:323:2 | while (...) ... | test.cpp:319:9:319:21 | ... \|\| ... | 1 | ... \|\| ... | { ... } | 0 | return ... |
| test.cpp:323:2:328:2 | while (...) ... | test.cpp:323:9:323:17 | ... ? ... : ... | | b, c | { ... } | c | return ... | | test.cpp:331:2:336:2 | while (...) ... | test.cpp:331:9:331:17 | ... ? ... : ... | | b, c | { ... } | c | return ... |
| test.cpp:336:2:341:2 | while (...) ... | test.cpp:336:9:336:21 | ... \|\| ... | 1 | b, c | { ... } | c | return ... | | test.cpp:344:2:349:2 | while (...) ... | test.cpp:344:9:344:21 | ... \|\| ... | 1 | b, c | { ... } | c | return ... |
| test.cpp:348:2:351:17 | do (...) ... | test.cpp:351:11:351:15 | 0 | | { ... } | { ... } | { ... } | return ... | | test.cpp:356:2:359:17 | do (...) ... | test.cpp:359:11:359:15 | 0 | | { ... } | { ... } | { ... } | return ... |
| test.cpp:361:2:364:2 | while (...) ... | test.cpp:361:9:361:21 | ... \|\| ... | 1 | ... \|\| ... | { ... } | 0 | while (...) ... | | test.cpp:369:2:372:2 | while (...) ... | test.cpp:369:9:369:21 | ... \|\| ... | 1 | ... \|\| ... | { ... } | 0 | while (...) ... |
| test.cpp:365:2:368:2 | while (...) ... | test.cpp:365:9:365:13 | ! ... | 1 | stop | { ... } | stop | while (...) ... | | test.cpp:373:2:376:2 | while (...) ... | test.cpp:373:9:373:13 | ! ... | 1 | stop | { ... } | stop | while (...) ... |
| test.cpp:369:2:373:2 | while (...) ... | test.cpp:369:9:369:21 | ... \|\| ... | 1 | b, c | { ... } | c | do (...) ... | | test.cpp:377:2:381:2 | while (...) ... | test.cpp:377:9:377:21 | ... \|\| ... | 1 | b, c | { ... } | c | do (...) ... |
| test.cpp:374:2:376:17 | do (...) ... | test.cpp:376:11:376:15 | 0 | | do (...) ... | { ... } | { ... } | return ... | | test.cpp:382:2:384:17 | do (...) ... | test.cpp:384:11:384:15 | 0 | | do (...) ... | { ... } | { ... } | return ... |
| test.cpp:384:2:386:2 | while (...) ... | test.cpp:384:9:384:12 | 1 | 1 | 1 | { ... } | | return ... | | test.cpp:392:2:394:2 | while (...) ... | test.cpp:392:9:392:12 | 1 | 1 | 1 | { ... } | | return ... |
| test.cpp:394:2:396:2 | while (...) ... | test.cpp:394:9:394:21 | ... , ... | | { ... } | { ... } | | | | test.cpp:402:2:404:2 | while (...) ... | test.cpp:402:9:402:21 | ... , ... | | { ... } | { ... } | | |
| test.cpp:404:3:408:3 | while (...) ... | test.cpp:404:10:404:13 | loop | 1 | loop | { ... } | | | | test.cpp:412:3:416:3 | while (...) ... | test.cpp:412:10:412:13 | loop | 1 | loop | { ... } | | |
| test.cpp:416:2:418:2 | for(...;...;...) ... | test.cpp:416:18:416:23 | ... < ... | 1 | i | { ... } | i | return ... | | test.cpp:424:2:426:2 | for(...;...;...) ... | test.cpp:424:18:424:23 | ... < ... | 1 | i | { ... } | i | return ... |
| test.cpp:424:2:425:2 | for(...;...;...) ... | test.cpp:424:18:424:23 | ... < ... | 1 | i | { ... } | i | return ... | | test.cpp:432:2:433:2 | for(...;...;...) ... | test.cpp:432:18:432:23 | ... < ... | 1 | i | { ... } | i | return ... |
| test.cpp:433:2:434:2 | for(...;...;...) ... | test.cpp:433:18:433:22 | 0 | 0 | | { ... } | 0 | return ... | | test.cpp:441:2:442:2 | for(...;...;...) ... | test.cpp:441:18:441:22 | 0 | 0 | | { ... } | 0 | return ... |
| test.cpp:559:3:564:3 | while (...) ... | test.cpp:559:9:559:15 | call to getBool | | call to getBool | { ... } | call to getBool | ExprStmt | | test.cpp:567:3:572:3 | while (...) ... | test.cpp:567:9:567:15 | call to getBool | | call to getBool | { ... } | call to getBool | ExprStmt |
| test.cpp:574:3:579:3 | while (...) ... | test.cpp:574:10:574:16 | call to getBool | | call to getBool | { ... } | call to getBool | ExprStmt | | test.cpp:582:3:587:3 | while (...) ... | test.cpp:582:10:582:16 | call to getBool | | call to getBool | { ... } | call to getBool | ExprStmt |

View File

@@ -2,28 +2,28 @@ edges
nodes nodes
| test.cpp:11:6:11:8 | definition of foo | semmle.label | definition of foo | | test.cpp:11:6:11:8 | definition of foo | semmle.label | definition of foo |
| test.cpp:111:6:111:8 | definition of foo | semmle.label | definition of foo | | test.cpp:111:6:111:8 | definition of foo | semmle.label | definition of foo |
| test.cpp:218:7:218:7 | definition of x | semmle.label | definition of x | | test.cpp:226:7:226:7 | definition of x | semmle.label | definition of x |
| test.cpp:241:6:241:6 | definition of i | semmle.label | definition of i | | test.cpp:249:6:249:6 | definition of i | semmle.label | definition of i |
| test.cpp:333:7:333:7 | definition of a | semmle.label | definition of a | | test.cpp:341:7:341:7 | definition of a | semmle.label | definition of a |
| test.cpp:358:7:358:7 | definition of a | semmle.label | definition of a | | test.cpp:366:7:366:7 | definition of a | semmle.label | definition of a |
| test.cpp:359:6:359:8 | definition of val | semmle.label | definition of val | | test.cpp:367:6:367:8 | definition of val | semmle.label | definition of val |
| test.cpp:414:9:414:9 | definition of j | semmle.label | definition of j | | test.cpp:422:9:422:9 | definition of j | semmle.label | definition of j |
| test.cpp:431:9:431:9 | definition of j | semmle.label | definition of j | | test.cpp:439:9:439:9 | definition of j | semmle.label | definition of j |
| test.cpp:452:6:452:6 | definition of x | semmle.label | definition of x | | test.cpp:460:6:460:6 | definition of x | semmle.label | definition of x |
| test.cpp:458:6:458:6 | definition of x | semmle.label | definition of x | | test.cpp:466:6:466:6 | definition of x | semmle.label | definition of x |
| test.cpp:464:6:464:6 | definition of x | semmle.label | definition of x | | test.cpp:472:6:472:6 | definition of x | semmle.label | definition of x |
| test.cpp:471:6:471:6 | definition of x | semmle.label | definition of x | | test.cpp:479:6:479:6 | definition of x | semmle.label | definition of x |
#select #select
| test.cpp:12:6:12:8 | foo | test.cpp:11:6:11:8 | definition of foo | test.cpp:11:6:11:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:11:6:11:8 | foo | foo | | test.cpp:12:6:12:8 | foo | test.cpp:11:6:11:8 | definition of foo | test.cpp:11:6:11:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:11:6:11:8 | foo | foo |
| test.cpp:113:6:113:8 | foo | test.cpp:111:6:111:8 | definition of foo | test.cpp:111:6:111:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:111:6:111:8 | foo | foo | | test.cpp:113:6:113:8 | foo | test.cpp:111:6:111:8 | definition of foo | test.cpp:111:6:111:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:111:6:111:8 | foo | foo |
| test.cpp:219:3:219:3 | x | test.cpp:218:7:218:7 | definition of x | test.cpp:218:7:218:7 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:218:7:218:7 | x | x | | test.cpp:227:3:227:3 | x | test.cpp:226:7:226:7 | definition of x | test.cpp:226:7:226:7 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:226:7:226:7 | x | x |
| test.cpp:243:13:243:13 | i | test.cpp:241:6:241:6 | definition of i | test.cpp:241:6:241:6 | definition of i | The variable $@ may not be initialized at this access. | test.cpp:241:6:241:6 | i | i | | test.cpp:251:13:251:13 | i | test.cpp:249:6:249:6 | definition of i | test.cpp:249:6:249:6 | definition of i | The variable $@ may not be initialized at this access. | test.cpp:249:6:249:6 | i | i |
| test.cpp:336:10:336:10 | a | test.cpp:333:7:333:7 | definition of a | test.cpp:333:7:333:7 | definition of a | The variable $@ may not be initialized at this access. | test.cpp:333:7:333:7 | a | a | | test.cpp:344:10:344:10 | a | test.cpp:341:7:341:7 | definition of a | test.cpp:341:7:341:7 | definition of a | The variable $@ may not be initialized at this access. | test.cpp:341:7:341:7 | a | a |
| test.cpp:369:10:369:10 | a | test.cpp:358:7:358:7 | definition of a | test.cpp:358:7:358:7 | definition of a | The variable $@ may not be initialized at this access. | test.cpp:358:7:358:7 | a | a | | test.cpp:377:10:377:10 | a | test.cpp:366:7:366:7 | definition of a | test.cpp:366:7:366:7 | definition of a | The variable $@ may not be initialized at this access. | test.cpp:366:7:366:7 | a | a |
| test.cpp:378:9:378:11 | val | test.cpp:359:6:359:8 | definition of val | test.cpp:359:6:359:8 | definition of val | The variable $@ may not be initialized at this access. | test.cpp:359:6:359:8 | val | val | | test.cpp:386:9:386:11 | val | test.cpp:367:6:367:8 | definition of val | test.cpp:367:6:367:8 | definition of val | The variable $@ may not be initialized at this access. | test.cpp:367:6:367:8 | val | val |
| test.cpp:417:10:417:10 | j | test.cpp:414:9:414:9 | definition of j | test.cpp:414:9:414:9 | definition of j | The variable $@ may not be initialized at this access. | test.cpp:414:9:414:9 | j | j | | test.cpp:425:10:425:10 | j | test.cpp:422:9:422:9 | definition of j | test.cpp:422:9:422:9 | definition of j | The variable $@ may not be initialized at this access. | test.cpp:422:9:422:9 | j | j |
| test.cpp:436:9:436:9 | j | test.cpp:431:9:431:9 | definition of j | test.cpp:431:9:431:9 | definition of j | The variable $@ may not be initialized at this access. | test.cpp:431:9:431:9 | j | j | | test.cpp:444:9:444:9 | j | test.cpp:439:9:439:9 | definition of j | test.cpp:439:9:439:9 | definition of j | The variable $@ may not be initialized at this access. | test.cpp:439:9:439:9 | j | j |
| test.cpp:454:2:454:2 | x | test.cpp:452:6:452:6 | definition of x | test.cpp:452:6:452:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:452:6:452:6 | x | x | | test.cpp:462:2:462:2 | x | test.cpp:460:6:460:6 | definition of x | test.cpp:460:6:460:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:460:6:460:6 | x | x |
| test.cpp:460:7:460:7 | x | test.cpp:458:6:458:6 | definition of x | test.cpp:458:6:458:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:458:6:458:6 | x | x | | test.cpp:468:7:468:7 | x | test.cpp:466:6:466:6 | definition of x | test.cpp:466:6:466:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:466:6:466:6 | x | x |
| test.cpp:467:2:467:2 | x | test.cpp:464:6:464:6 | definition of x | test.cpp:464:6:464:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:464:6:464:6 | x | x | | test.cpp:475:2:475:2 | x | test.cpp:472:6:472:6 | definition of x | test.cpp:472:6:472:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:472:6:472:6 | x | x |
| test.cpp:474:7:474:7 | x | test.cpp:471:6:471:6 | definition of x | test.cpp:471:6:471:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:471:6:471:6 | x | x | | test.cpp:482:7:482:7 | x | test.cpp:479:6:479:6 | definition of x | test.cpp:479:6:479:6 | definition of x | The variable $@ may not be initialized at this access. | test.cpp:479:6:479:6 | x | x |

View File

@@ -156,11 +156,12 @@ int absCorrect2(int i) {
return j; // correct: j always initialized before use return j; // correct: j always initialized before use
} }
typedef __builtin_va_list va_list;
#define va_start(v, l) __builtin_va_start(v,l)
#define va_end(v) __builtin_va_end(v)
#define va_arg(v, l) __builtin_va_arg(v,l)
#define va_copy(d, s) __builtin_va_copy(d,s)
typedef void *va_list;
#define va_start(ap, parmN)
#define va_end(ap)
#define va_arg(ap, type) ((type)0)
#define NULL 0 #define NULL 0
// Variadic initialisation // Variadic initialisation
@@ -192,6 +193,13 @@ void test16() {
use(foo); // BAD (NOT REPORTED) use(foo); // BAD (NOT REPORTED)
} }
void test_va_copy(va_list va) {
va_list va2;
va_copy(va2, va); // GOOD -- this is an initialization
use(va2);
va_end(va2);
}
bool test17(bool b) { bool test17(bool b) {
int foo; int foo;
int *p = nullptr; int *p = nullptr;

View File

@@ -17,3 +17,4 @@
| test.cpp:229:15:229:35 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:231:16:231:19 | { ... } | This catch block | | test.cpp:229:15:229:35 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:231:16:231:19 | { ... } | This catch block |
| test.cpp:242:14:242:34 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:243:34:243:36 | { ... } | This catch block | | test.cpp:242:14:242:34 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:243:34:243:36 | { ... } | This catch block |
| test.cpp:276:17:276:31 | new[] | This allocation cannot return null. $@ is unnecessary. | test.cpp:277:8:277:12 | ! ... | This check | | test.cpp:276:17:276:31 | new[] | This allocation cannot return null. $@ is unnecessary. | test.cpp:277:8:277:12 | ! ... | This check |
| test.cpp:288:19:288:47 | new[] | This allocation cannot throw. $@ is unnecessary. | test.cpp:291:30:293:5 | { ... } | This catch block |

View File

@@ -282,7 +282,7 @@ namespace qhelp {
} }
// BAD: the allocation won't throw an exception, but // BAD: the allocation won't throw an exception, but
// instead return a null pointer. [NOT DETECTED] // instead return a null pointer.
void bad2(std::size_t length) noexcept { void bad2(std::size_t length) noexcept {
try { try {
int* dest = new(std::nothrow) int[length]; int* dest = new(std::nothrow) int[length];

View File

@@ -3,6 +3,7 @@ using System.Collections.Concurrent;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Semmle.Extraction.Entities;
using Semmle.Util; using Semmle.Util;
namespace Semmle.Extraction.CSharp.Entities namespace Semmle.Extraction.CSharp.Entities
@@ -89,13 +90,21 @@ namespace Semmle.Extraction.CSharp.Entities
trapFile.compilation_finished(this, (float)p.Total.Cpu.TotalSeconds, (float)p.Total.Elapsed.TotalSeconds); trapFile.compilation_finished(this, (float)p.Total.Cpu.TotalSeconds, (float)p.Total.Elapsed.TotalSeconds);
} }
public void PopulateAggregatedMessages()
{
ExtractionMessage.groupedMessageCounts.ForEach(pair =>
{
Context.TrapWriter.Writer.compilation_info(this, $"Extractor message count for group '{pair.Key}'", pair.Value.ToString());
});
}
public override void WriteId(EscapingTextWriter trapFile) public override void WriteId(EscapingTextWriter trapFile)
{ {
trapFile.Write(hashCode); trapFile.Write(hashCode);
trapFile.Write(";compilation"); trapFile.Write(";compilation");
} }
public override Location ReportingLocation => throw new NotImplementedException(); public override Microsoft.CodeAnalysis.Location ReportingLocation => throw new NotImplementedException();
public override bool NeedsPopulation => Context.IsAssemblyScope; public override bool NeedsPopulation => Context.IsAssemblyScope;

View File

@@ -21,7 +21,7 @@ namespace Semmle.Extraction.CSharp.Entities
public override Microsoft.CodeAnalysis.Location ReportingLocation => public override Microsoft.CodeAnalysis.Location ReportingLocation =>
IsCompilerGeneratedDelegate() IsCompilerGeneratedDelegate()
? Symbol.ContainingType.GetSymbolLocation() ? Symbol.ContainingType.GetSymbolLocation()
: Symbol.GetSymbolLocation(); : BodyDeclaringSymbol.GetSymbolLocation();
public override bool NeedsPopulation => base.NeedsPopulation || IsCompilerGeneratedDelegate(); public override bool NeedsPopulation => base.NeedsPopulation || IsCompilerGeneratedDelegate();

View File

@@ -250,6 +250,8 @@ namespace Semmle.Extraction.CSharp
public void LogPerformance(Entities.PerformanceMetrics p) => compilationEntity.PopulatePerformance(p); public void LogPerformance(Entities.PerformanceMetrics p) => compilationEntity.PopulatePerformance(p);
public void ExtractAggregatedMessages() => compilationEntity.PopulateAggregatedMessages();
#nullable restore warnings #nullable restore warnings
/// <summary> /// <summary>

View File

@@ -458,6 +458,7 @@ namespace Semmle.Extraction.CSharp
sw.Restart(); sw.Restart();
analyser.PerformExtraction(options.Threads); analyser.PerformExtraction(options.Threads);
analyser.ExtractAggregatedMessages();
sw.Stop(); sw.Stop();
var cpuTime2 = currentProcess.TotalProcessorTime; var cpuTime2 = currentProcess.TotalProcessorTime;
var userTime2 = currentProcess.UserProcessorTime; var userTime2 = currentProcess.UserProcessorTime;

View File

@@ -26,6 +26,7 @@ codeql_csharp_library(
], ],
"//conditions:default": [], "//conditions:default": [],
}), }),
internals_visible_to = ["Semmle.Extraction.CSharp"],
visibility = ["//csharp:__subpackages__"], visibility = ["//csharp:__subpackages__"],
deps = [ deps = [
"//csharp/extractor/Semmle.Util", "//csharp/extractor/Semmle.Util",

View File

@@ -1,4 +1,5 @@
using System.IO; using System.Collections.Concurrent;
using System.IO;
using System.Threading; using System.Threading;
using Semmle.Util; using Semmle.Util;
@@ -7,6 +8,8 @@ namespace Semmle.Extraction.Entities
internal class ExtractionMessage : FreshEntity internal class ExtractionMessage : FreshEntity
{ {
private static readonly int limit = EnvironmentVariables.TryGetExtractorNumberOption<int>("MESSAGE_LIMIT") ?? 10000; private static readonly int limit = EnvironmentVariables.TryGetExtractorNumberOption<int>("MESSAGE_LIMIT") ?? 10000;
internal static readonly ConcurrentDictionary<string, int> groupedMessageCounts = [];
private static int messageCount = 0; private static int messageCount = 0;
private readonly Message msg; private readonly Message msg;
@@ -25,6 +28,10 @@ namespace Semmle.Extraction.Entities
protected override void Populate(TextWriter trapFile) protected override void Populate(TextWriter trapFile)
{ {
// For the time being we're counting the number of messages per severity, we could introduce other groupings in the future
var key = msg.Severity.ToString();
groupedMessageCounts.AddOrUpdate(key, 1, (_, c) => c + 1);
if (!bypassLimit) if (!bypassLimit)
{ {
var val = Interlocked.Increment(ref messageCount); var val = Interlocked.Increment(ref messageCount);

View File

@@ -5,6 +5,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj" /> <ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj" />
<InternalsVisibleTo Include="Semmle.Extraction.CSharp" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\.paket\Paket.Restore.targets" /> <Import Project="..\..\.paket\Paket.Restore.targets" />
</Project> </Project>

View File

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

View File

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

View File

@@ -7,3 +7,5 @@ extractorMessagesLeachedLimit
compilationInfo compilationInfo
| Compiler diagnostic count for CS0103 | 3.0 | | Compiler diagnostic count for CS0103 | 3.0 |
| Compiler diagnostic count for CS8019 | 7.0 | | Compiler diagnostic count for CS8019 | 7.0 |
| Extractor message count for group 'Error' | 8.0 |
| Extractor message count for group 'Warning' | 1.0 |

View File

@@ -11,7 +11,8 @@ query predicate extractorMessagesLeachedLimit(ExtractorMessage msg) {
query predicate compilationInfo(string key, float value) { query predicate compilationInfo(string key, float value) {
exists(Compilation c, string infoValue | exists(Compilation c, string infoValue |
infoValue = c.getInfo(key) and key.matches("Compiler diagnostic count for%") infoValue = c.getInfo(key) and
key.matches(["Compiler diagnostic count for%", "Extractor message count for group%"])
| |
value = infoValue.toFloat() value = infoValue.toFloat()
) )

View File

@@ -4,7 +4,7 @@ import semmle.code.csharp.commons.Diagnostics
query predicate compilationInfo(string key, float value) { query predicate compilationInfo(string key, float value) {
key != "Resolved references" and key != "Resolved references" and
key != "Resolved assembly conflicts" and key != "Resolved assembly conflicts" and
not key.matches("Compiler diagnostic count for%") and not key.matches(["Compiler diagnostic count for%", "Extractor message count for group%"]) and
exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) | exists(Compilation c, string infoKey, string infoValue | infoValue = c.getInfo(infoKey) |
key = infoKey and key = infoKey and
value = infoValue.toFloat() value = infoValue.toFloat()

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