Compare commits

..

67 Commits

Author SHA1 Message Date
Nick Rolfe
3ef203653f DataFlow: use doublyBoundedFastTC in flowPath 2024-03-27 11:00:56 +00:00
Dave Bartolomeo
a950de36a0 Merge pull request #16050 from github/dbartol/more-test-fixes
Remove unused data extension in test
2024-03-25 20:50:09 -04:00
Dave Bartolomeo
c11b8f9d51 Remove unused data extension in test 2024-03-25 19:14:54 -04:00
Max Schaefer
ff23f572d0 Merge pull request #16038 from github/max-schaefer/string-break-qhelp
Go: Improve QHelp for `go/unsafe-quoting`.
2024-03-25 20:10:02 +00:00
Max Schaefer
5bc710b406 Apply suggestions from code review
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2024-03-25 19:48:56 +00:00
Dave Bartolomeo
98bf5269a0 Merge pull request #16040 from github/dbartol/qltest-model
Use correct model pack name in qltest data extension
2024-03-25 15:29:16 -04:00
Chris Smowton
f5ebd3d501 Merge pull request #16047 from github/smowton/admin/update-java-supported-version
Update Java version supported to 22
2024-03-25 18:42:35 +00:00
Chris Smowton
757b9bb5fa Update Java version supported to 22 2024-03-25 18:01:30 +00:00
Chris Smowton
6fc99e3ad6 Merge pull request #16023 from smowton/smowton/feature/jdk22-support
Java: support Java 22 language features
2024-03-25 17:58:50 +00:00
Chris Smowton
dcebcc35b6 Rename getPatternAtIndex 2024-03-25 16:36:38 +00:00
Chris Smowton
568bddc4a9 Add test cases for cases falling directly out of switch blocks 2024-03-25 16:31:40 +00:00
Chris Smowton
17193ac11b Distinguish record patterns that do or don't declare identifiers 2024-03-25 16:31:40 +00:00
Chris Smowton
a4401963f5 Use getAPattern 2024-03-25 16:31:39 +00:00
Chris Smowton
f347784ec2 autoformat 2024-03-25 16:31:39 +00:00
Chris Smowton
3d9bc6fc89 Note pattern-cases may be missing some type-accesses 2024-03-25 16:31:39 +00:00
Chris Smowton
5e0961b348 Account for new possible child index gap 2024-03-25 16:31:39 +00:00
Chris Smowton
9fa2f19990 Add test for guards in the presence of fall-through between pattern and constant cases 2024-03-25 16:31:39 +00:00
Chris Smowton
c48e64e536 Add tests for the combination of anonymous labels and a guard 2024-03-25 16:31:39 +00:00
Chris Smowton
1e0766dffa Add tests for case statement type test dominance against anonymous labels and fall-through 2024-03-25 16:31:39 +00:00
Chris Smowton
f2ff6c476a Add printast tests for anonymous variables 2024-03-25 16:31:38 +00:00
Chris Smowton
5cb5ee026c Fix pretty-printing of anonymous vars and multiple patterns; add test 2024-03-25 16:31:38 +00:00
Chris Smowton
f317f782ae Add test for control-flow with mixed patterns, constants and fall-through 2024-03-25 16:31:38 +00:00
Chris Smowton
6cf956d07a Add CFG test for anonymous variables and fall-throughs with pattern cases 2024-03-25 16:31:38 +00:00
Chris Smowton
cc8dcf63b0 Convert test to use an anonymous local 2024-03-25 16:31:38 +00:00
Chris Smowton
ee36e3b72b autoformat 2024-03-25 16:31:38 +00:00
Chris Smowton
403e86878c Don't mistake a rule case for a fall-through edge 2024-03-25 16:31:37 +00:00
Chris Smowton
5243a62a41 Accept test changes 2024-03-25 16:31:37 +00:00
Chris Smowton
c0874ab04b Fix pattern-case variable pretty-printer 2024-03-25 16:31:37 +00:00
Chris Smowton
f66811048d Fix next-normal-statement predicate 2024-03-25 16:31:37 +00:00
Chris Smowton
bc0724e2b3 Add change note 2024-03-25 16:31:37 +00:00
Chris Smowton
d5443b3f10 Remove dead code 2024-03-25 16:31:37 +00:00
Chris Smowton
29e93edf90 Dataflow: restrict pattern-case flow to unique patterns. 2024-03-25 16:31:37 +00:00
Chris Smowton
00c7dd5f92 Fix a stray use of getPattern 2024-03-25 16:31:36 +00:00
Chris Smowton
e59487a324 Don't regard cases with multiple patterns as conducting a type test 2024-03-25 16:31:36 +00:00
Chris Smowton
c7cb885e71 Add missing javadoc and getUniquePattern predicate 2024-03-25 16:31:36 +00:00
Chris Smowton
f44becea7f Implement multiple pattern case and fall-through pattern case support 2024-03-25 16:31:36 +00:00
Chris Smowton
c283894b4b Fix typo 2024-03-25 16:31:36 +00:00
Chris Smowton
33b807f3bb Parameters and local variables: add isAnonymous predicate 2024-03-25 16:31:36 +00:00
Edward Minnix III
7377cbb46e Merge pull request #15930 from egregius313/egregius313/csharp/mad/database/dapper-sources
C#: Sources for the `Dapper` database library
2024-03-25 11:21:51 -04:00
Rasmus Wriedt Larsen
d516db6abc Merge pull request #15903 from yoff/python/test-MaD-keyword-argument
Python: test MaD syntax for keyword argument
2024-03-25 15:51:49 +01:00
Dave Bartolomeo
d805bbcd27 Use correct model pack name in qltest data extension 2024-03-25 10:31:11 -04:00
Max Schaefer
120fb93c23 Go: Improve QHelp for go/unsafe-quoting. 2024-03-25 13:32:51 +00:00
Paolo Tranquilli
dea922958b Merge pull request #16034 from github/redsun82/swift-move-integration-tests-to-internal
Swift: prepare integration tests for internal running
2024-03-25 14:08:47 +01:00
Paolo Tranquilli
9c9f4b956e Swift: fix db in diagnostics_test_utils.py 2024-03-25 13:53:27 +01:00
Paolo Tranquilli
7f53509022 Merge branch 'main' into redsun82/swift-move-integration-tests-to-internal 2024-03-25 12:22:00 +01:00
Paolo Tranquilli
6707fc3a7c Swift: remove wrong flag in runner.py 2024-03-25 12:20:13 +01:00
Paolo Tranquilli
148033e020 Swift: fix assertion diagnostics test 2024-03-25 12:05:22 +01:00
Paolo Tranquilli
ca5d85c57e Merge branch 'main' into redsun82/swift-move-integration-tests-to-internal 2024-03-25 11:56:48 +01:00
Paolo Tranquilli
0fa40af131 Swift: fix last references to old integration test location 2024-03-25 11:49:19 +01:00
Paolo Tranquilli
5a771ad2cf Swift: bump python version 2024-03-25 10:42:16 +01:00
Paolo Tranquilli
762b4ce42e Swift: prepare integration tests for internal running
This harmonizes Swift integration tests with the rest of the repository,
to prepare for the internal integration test runner to run them. The
stripped down runner is kept compatible, so that current CI can still
use it now. Maybe it will be kept for developer use.

This PR includes:
* moving the integration tests inside `ql`
* editing `qlpack.yml` so that the internal runner can use it
* change database directory to be `test-db` rather than `db`
2024-03-25 10:17:55 +01:00
Michael Nebel
a07ee8e961 C#: Update the AsList model to a value flow model. 2024-03-22 14:40:25 +01:00
Michael Nebel
ca72b0583d C#: Update source and sink expected test output. 2024-03-22 13:59:47 +01:00
Ed Minnix
4b13ad1310 Fix flow summary tests 2024-03-22 13:46:20 +01:00
Ed Minnix
9ed8ca27a1 Fix test and model 2024-03-22 13:46:19 +01:00
Ed Minnix
1f04229def Fix typo 2024-03-22 13:46:19 +01:00
Ed Minnix
73b4e8fe6a Add WithElement identifier to AsList method 2024-03-22 13:46:19 +01:00
Ed Minnix
9b23bfa038 Execute methods which return objects
The `Execute` method returns `int` for "number of rows affected". But
some of the other `Execute*` methods return objects.
2024-03-22 13:46:19 +01:00
Ed Minnix
5885938eaf Use wildcard signatures for Query methods 2024-03-22 13:46:19 +01:00
Ed Minnix
8223781978 Fix FlowSummaries tests 2024-03-22 13:46:19 +01:00
Ed Minnix
5ca6b40c34 Change note 2024-03-22 13:46:18 +01:00
Ed Minnix
23aeb1d878 Add tests 2024-03-22 13:46:18 +01:00
Ed Minnix
98285b5171 Add AsList summary 2024-03-22 13:46:18 +01:00
Ed Minnix
87ad170067 Dapper source models 2024-03-22 13:46:18 +01:00
yoff
c520cb6d58 Merge branch 'main' into python/test-MaD-keyword-argument 2024-03-22 10:56:08 +01:00
Rasmus Lerchedahl Petersen
eef60c9ad2 python: add test for "ReturnValue.TupleElement[0,1]"
also synchronise files
2024-03-22 10:54:12 +01:00
Rasmus Lerchedahl Petersen
533b63743b Python: test MaD syntax for keyword argument
use the combined positional/keyword syntax as
that is what we will probably mostly use.
2024-03-13 15:28:34 +01:00
218 changed files with 1499 additions and 198 deletions

View File

@@ -40,7 +40,7 @@ jobs:
uses: github/codeql-action/init@main
# Override language selection by uncommenting this and choosing your languages
with:
languages: csharp, cpp
languages: csharp
config-file: ./.github/codeql/codeql-config.yml
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
@@ -57,19 +57,6 @@ jobs:
- run: |
dotnet build csharp
- name: "[Ubuntu] Remove GCC 13 from runner image"
shell: bash
run: |
sudo rm -f /etc/apt/sources.list.d/ubuntu-toolchain-r-ubuntu-test-jammy.list
sudo apt-get update
sudo apt-get install -y --allow-downgrades libc6=2.35-* libc6-dev=2.35-* libstdc++6=12.3.0-* libgcc-s1=12.3.0-*
- name: "Build Swift extractor using Bazel"
run: |
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 shutdown
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@main

View File

@@ -18,7 +18,7 @@ bazel_dep(name = "rules_pkg", version = "0.9.1")
bazel_dep(name = "rules_nodejs", version = "6.0.3")
bazel_dep(name = "rules_python", version = "0.31.0")
bazel_dep(name = "bazel_skylib", version = "1.5.0")
bazel_dep(name = "abseil-cpp", version = "20240116.1", repo_name = "absl")
bazel_dep(name = "abseil-cpp", version = "20240116.0", repo_name = "absl")
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
bazel_dep(name = "fmt", version = "10.0.0")

View File

@@ -28,7 +28,6 @@ provide:
- "misc/suite-helpers/qlpack.yml"
- "ruby/extractor-pack/codeql-extractor.yml"
- "swift/extractor-pack/codeql-extractor.yml"
- "swift/integration-tests/qlpack.yml"
- "ql/extractor-pack/codeql-extractor.yml"
- ".github/codeql/extensions/**/codeql-pack.yml"

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added new source models for the `Dapper` package. These models can be enabled by enabling the `database` threat model.

View File

@@ -58,3 +58,54 @@ extensions:
- ["Dapper", "SqlMapper", False, "QuerySingleOrDefaultAsync", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>)", "", "Argument[1]", "sql-injection", "manual"]
- ["Dapper", "SqlMapper", False, "QuerySingleOrDefaultAsync", "(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>)", "", "Argument[2]", "sql-injection", "manual"]
- ["Dapper", "SqlMapper", False, "QuerySingleOrDefaultAsync<T>", "(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>)", "", "Argument[1]", "sql-injection", "manual"]
- addsTo:
pack: codeql/csharp-all
extensible: sourceModel
data:
- ["Dapper", "SqlMapper", False, "ExecuteReader", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "ExecuteReaderAsync", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "ExecuteScalar", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "ExecuteScalar<T>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "ExecuteScalarAsync", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "ExecuteScalarAsync<T>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "Query", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "Query<T>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "Query<TFirst,TSecond,TReturn>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "Query<TFirst,TSecond,TThird,TFourth,TFifth,TReturn>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "Query<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TReturn>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "Query<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TSeventh,TReturn>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "Query<TFirst,TSecond,TThird,TFourth,TReturn>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "Query<TFirst,TSecond,TThird,TReturn>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "Query<TReturn>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryAsync", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryAsync<T>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryAsync<TFirst,TSecond,TReturn>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryAsync<TFirst,TSecond,TThird,TFourth,TFifth,TReturn>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryAsync<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TReturn>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryAsync<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TSeventh,TReturn>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryAsync<TFirst,TSecond,TThird,TFourth,TReturn>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryAsync<TFirst,TSecond,TThird,TReturn>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryAsync<TReturn>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryFirst", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryFirst<T>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryFirstAsync", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryFirstAsync<T>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryFirstOrDefault", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryFirstOrDefault<T>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryFirstOrDefaultAsync", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryFirstOrDefaultAsync<T>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryMultiple", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QueryMultipleAsync", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QuerySingle", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QuerySingle<T>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QuerySingleAsync", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QuerySingleAsync<T>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QuerySingleOrDefault", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QuerySingleOrDefault<T>", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QuerySingleOrDefaultAsync", "", "", "ReturnValue", "database", "manual"]
- ["Dapper", "SqlMapper", False, "QuerySingleOrDefaultAsync<T>", "", "", "ReturnValue", "database", "manual"]
- addsTo:
pack: codeql/csharp-all
extensible: summaryModel
data:
- ["Dapper", "SqlMapper", False, "AsList<T>", "(System.Collections.Generic.IEnumerable<T>)", "", "Argument[0].Element", "ReturnValue.Element", "value", "manual"]

View File

@@ -0,0 +1,7 @@
extensions:
- addsTo:
pack: codeql/threat-models
extensible: threatModelConfiguration
data:
- ["database", true, 0]

View File

@@ -0,0 +1,12 @@
import csharp
import semmle.code.csharp.security.dataflow.flowsources.FlowSources
import TestUtilities.InlineFlowTest
import TaintFlowTest<DatabaseConfig>
module DatabaseConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof ThreatModelFlowSource }
predicate isSink(DataFlow::Node sink) {
exists(MethodCall mc | mc.getTarget().hasName("Sink") | sink.asExpr() = mc.getArgument(0))
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.Data;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Threading.Tasks;
using Dapper;
namespace Test
{
class UseDapper
{
public static void Bad01(string connectionString, string query)
{
using (var connection = new SqlConnection(connectionString))
{
var result = connection.Query<object>(query);
Sink(result); // $ hasTaintFlow=line:16
}
}
public static async Task Bad02(string connectionString, string query)
{
using (var connection = new SqlConnection(connectionString))
{
var result = await connection.QueryAsync<object>(query);
Sink(result); // $ hasTaintFlow=line:25
}
}
public static void Bad03(string connectionString, string query)
{
using (var connection = new SqlConnection(connectionString))
{
var result = connection.QueryFirst(query);
Sink(result); // $ hasTaintFlow=line:34
}
}
public static void Bad04(string connectionString, string query)
{
using (var connection = new SqlConnection(connectionString))
{
var results = connection.Query<object>(query).AsList();
Sink(results[0]); // $ hasTaintFlow=line:43
}
}
public static void Sink(object o) { }
}
}

View File

@@ -0,0 +1,5 @@
semmle-extractor-options: /nostdlib /noconfig
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../../resources/stubs/Dapper/2.1.24/Dapper.csproj
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../../resources/stubs/System.Data.SqlClient/4.8.5/System.Data.SqlClient.csproj
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../../resources/stubs/System.Data.SQLite/1.0.118/System.Data.SQLite.csproj
semmle-extractor-options: ${testdir}/../../../../../../resources/stubs/System.Windows.cs

View File

@@ -1,4 +1,95 @@
source
| Dapper;SqlMapper;false;ExecuteReader;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteReader;(System.Data.IDbConnection,Dapper.CommandDefinition,System.Data.CommandBehavior);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteReader;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteReaderAsync;(System.Data.Common.DbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteReaderAsync;(System.Data.Common.DbConnection,Dapper.CommandDefinition,System.Data.CommandBehavior);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteReaderAsync;(System.Data.Common.DbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteReaderAsync;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteReaderAsync;(System.Data.IDbConnection,Dapper.CommandDefinition,System.Data.CommandBehavior);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteReaderAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteScalar;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteScalar;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteScalar<T>;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteScalar<T>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteScalarAsync;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteScalarAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteScalarAsync<T>;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;ExecuteScalarAsync<T>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;Query;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Boolean,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;Query;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Boolean,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;Query<T>;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;Query<T>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Boolean,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;Query<TFirst,TSecond,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;Query<TFirst,TSecond,TThird,TFourth,TFifth,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;Query<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;Query<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TSeventh,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TSeventh,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;Query<TFirst,TSecond,TThird,TFourth,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;Query<TFirst,TSecond,TThird,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;Query<TReturn>;(System.Data.IDbConnection,System.String,System.Type[],System.Func<System.Object[],TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync;(System.Data.IDbConnection,System.Type,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync<T>;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync<T>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync<TFirst,TSecond,TReturn>;(System.Data.IDbConnection,Dapper.CommandDefinition,System.Func<TFirst,TSecond,TReturn>,System.String);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync<TFirst,TSecond,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync<TFirst,TSecond,TThird,TFourth,TFifth,TReturn>;(System.Data.IDbConnection,Dapper.CommandDefinition,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TReturn>,System.String);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync<TFirst,TSecond,TThird,TFourth,TFifth,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TReturn>;(System.Data.IDbConnection,Dapper.CommandDefinition,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TReturn>,System.String);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TSeventh,TReturn>;(System.Data.IDbConnection,Dapper.CommandDefinition,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TSeventh,TReturn>,System.String);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TSeventh,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TSeventh,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync<TFirst,TSecond,TThird,TFourth,TReturn>;(System.Data.IDbConnection,Dapper.CommandDefinition,System.Func<TFirst,TSecond,TThird,TFourth,TReturn>,System.String);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync<TFirst,TSecond,TThird,TFourth,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync<TFirst,TSecond,TThird,TReturn>;(System.Data.IDbConnection,Dapper.CommandDefinition,System.Func<TFirst,TSecond,TThird,TReturn>,System.String);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync<TFirst,TSecond,TThird,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryAsync<TReturn>;(System.Data.IDbConnection,System.String,System.Type[],System.Func<System.Object[],TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirst;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirst;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirst<T>;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirst<T>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstAsync;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstAsync;(System.Data.IDbConnection,System.Type,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstAsync<T>;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstAsync<T>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstOrDefault;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstOrDefault;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstOrDefault<T>;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstOrDefault<T>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstOrDefaultAsync;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstOrDefaultAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstOrDefaultAsync;(System.Data.IDbConnection,System.Type,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstOrDefaultAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstOrDefaultAsync<T>;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryFirstOrDefaultAsync<T>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryMultiple;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryMultiple;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryMultipleAsync;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QueryMultipleAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingle;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingle;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingle<T>;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingle<T>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleAsync;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleAsync;(System.Data.IDbConnection,System.Type,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleAsync<T>;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleAsync<T>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleOrDefault;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleOrDefault;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleOrDefault<T>;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleOrDefault<T>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleOrDefaultAsync;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleOrDefaultAsync;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleOrDefaultAsync;(System.Data.IDbConnection,System.Type,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleOrDefaultAsync;(System.Data.IDbConnection,System.Type,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleOrDefaultAsync<T>;(System.Data.IDbConnection,Dapper.CommandDefinition);;ReturnValue;database;manual |
| Dapper;SqlMapper;false;QuerySingleOrDefaultAsync<T>;(System.Data.IDbConnection,System.String,System.Object,System.Data.IDbTransaction,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;ReturnValue;database;manual |
| Microsoft.Extensions.Configuration;EnvironmentVariablesExtensions;false;AddEnvironmentVariables;(Microsoft.Extensions.Configuration.IConfigurationBuilder);;Argument[0];environment;manual |
| Microsoft.Extensions.Configuration;EnvironmentVariablesExtensions;false;AddEnvironmentVariables;(Microsoft.Extensions.Configuration.IConfigurationBuilder);;ReturnValue;environment;manual |
| Microsoft.Extensions.Configuration;EnvironmentVariablesExtensions;false;AddEnvironmentVariables;(Microsoft.Extensions.Configuration.IConfigurationBuilder,System.Action<Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationSource>);;Argument[0];environment;manual |
@@ -645,6 +736,7 @@ summary
| Dapper;SqlMapper+GridReader;false;Read<TFirst,TSecond,TThird,TFourth,TReturn>;(System.Func<TFirst,TSecond,TThird,TFourth,TReturn>,System.String,System.Boolean);;Argument[0];Argument[0].Parameter[delegate-self];value;hq-generated |
| Dapper;SqlMapper+GridReader;false;Read<TFirst,TSecond,TThird,TReturn>;(System.Func<TFirst,TSecond,TThird,TReturn>,System.String,System.Boolean);;Argument[0];Argument[0].Parameter[delegate-self];value;hq-generated |
| Dapper;SqlMapper+GridReader;false;Read<TReturn>;(System.Type[],System.Func<System.Object[],TReturn>,System.String,System.Boolean);;Argument[1];Argument[1].Parameter[delegate-self];value;hq-generated |
| Dapper;SqlMapper;false;AsList<T>;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;ReturnValue.Element;value;manual |
| Dapper;SqlMapper;false;Query<TFirst,TSecond,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated |
| Dapper;SqlMapper;false;Query<TFirst,TSecond,TThird,TFourth,TFifth,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated |
| Dapper;SqlMapper;false;Query<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated |

View File

@@ -8,6 +8,7 @@
| Dapper;SqlMapper+GridReader;false;Read<TFirst,TSecond,TThird,TFourth,TReturn>;(System.Func<TFirst,TSecond,TThird,TFourth,TReturn>,System.String,System.Boolean);;Argument[0];Argument[0].Parameter[delegate-self];value;hq-generated |
| Dapper;SqlMapper+GridReader;false;Read<TFirst,TSecond,TThird,TReturn>;(System.Func<TFirst,TSecond,TThird,TReturn>,System.String,System.Boolean);;Argument[0];Argument[0].Parameter[delegate-self];value;hq-generated |
| Dapper;SqlMapper+GridReader;false;Read<TReturn>;(System.Type[],System.Func<System.Object[],TReturn>,System.String,System.Boolean);;Argument[1];Argument[1].Parameter[delegate-self];value;hq-generated |
| Dapper;SqlMapper;false;AsList<T>;(System.Collections.Generic.IEnumerable<T>);;Argument[0].Element;ReturnValue.Element;value;manual |
| Dapper;SqlMapper;false;Query<TFirst,TSecond,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated |
| Dapper;SqlMapper;false;Query<TFirst,TSecond,TThird,TFourth,TFifth,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated |
| Dapper;SqlMapper;false;Query<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TReturn>;(System.Data.IDbConnection,System.String,System.Func<TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TReturn>,System.Object,System.Data.IDbTransaction,System.Boolean,System.String,System.Nullable<System.Int32>,System.Nullable<System.Data.CommandType>);;Argument[2];Argument[2].Parameter[delegate-self];value;hq-generated |

View File

@@ -17,7 +17,7 @@
.NET 5, .NET 6, .NET 7, .NET 8","``.sln``, ``.csproj``, ``.cs``, ``.cshtml``, ``.xaml``"
Go (aka Golang), "Go up to 1.22", "Go 1.11 or more recent", ``.go``
Java,"Java 7 to 21 [5]_","javac (OpenJDK and Oracle JDK),
Java,"Java 7 to 22 [5]_","javac (OpenJDK and Oracle JDK),
Eclipse compiler for Java (ECJ) [6]_",``.java``
Kotlin [7]_,"Kotlin 1.5.0 to 1.9.2\ *x*","kotlinc",``.kt``
@@ -33,7 +33,7 @@
.. [2] Objective-C, Objective-C++, C++/CLI, and C++/CX are not supported.
.. [3] Support for the clang-cl compiler is preliminary.
.. [4] Support for the Arm Compiler (armcc) is preliminary.
.. [5] Builds that execute on Java 7 to 21 can be analyzed. The analysis understands Java 21 standard language features.
.. [5] Builds that execute on Java 7 to 22 can be analyzed. The analysis understands Java 22 standard language features.
.. [6] ECJ is supported when the build invokes it via the Maven Compiler plugin or the Takari Lifecycle plugin.
.. [7] Kotlin support is currently in beta.
.. [8] JSX and Flow code, YAML, JSON, HTML, and XML files may also be analyzed with JavaScript files.

View File

@@ -5,19 +5,21 @@
<overview>
<p>
Code that constructs a string containing a quoted substring needs to ensure that any user-provided
data embedded in between the quotes does not itself contain a quote. Otherwise the embedded data
could (accidentally or intentionally) change the structure of the overall string by terminating
the quoted substring early, with potentially severe consequences. If, for example, the string is
later interpreted as an operating-system command or database query, a malicious attacker may be
able to craft input data that enables a command injection or SQL injection attack.
Code that constructs a quoted string literal containing user-provided data needs to ensure that
this data does not itself contain a quote. Otherwise the embedded data could (accidentally or
intentionally) terminate the string literal early and thereby change the structure of the overall
string, with potentially severe consequences. If, for example, the string is later used as
part of an operating-system command or database query, an attacker may be able to craft input data
that injects a malicious command.
</p>
</overview>
<recommendation>
<p>
Sanitize the embedded data appropriately to ensure quotes are escaped, or use an API that does
not rely on manually constructing quoted substrings.
not rely on manually constructing quoted substrings. Make sure to use the appropriate escaping
mechanism, for example, double quoting for SQL strings or backslash escaping for shell commands.
When using backslash escaping, the backslash character itself must also be escaped.
</p>
</recommendation>
@@ -29,17 +31,38 @@ then embeds it into a SQL query built using the Squirrel library.
</p>
<sample src="StringBreak.go"/>
<p>
Note that while Squirrel provides a structured API for building SQL queries that mitigates against
common causes of SQL injection vulnerabilities, this code is still vulnerable: if the JSON-encoded
representation of <code>version</code> contains a single quote, this will prematurely close the
surrounding string, changing the structure of the SQL expression being constructed. This could be
exploited to mount a SQL injection attack.
Note that JSON encoding does not escape single quotes in any way, so this code is vulnerable: any
single-quote character in <code>version</code> will prematurely close the surrounding string literal,
changing the structure of the SQL expression being constructed. This could be exploited to mount
a SQL injection attack.
</p>
<p>
To fix this vulnerability, use Squirrel's placeholder syntax, which avoids the need to explicitly
construct a quoted string.
To fix this vulnerability, use the placeholder syntax from Squirrel's structured API for building
queries, which avoids the need to explicitly construct a quoted string.
</p>
<sample src="StringBreakGood.go"/>
<p>
In situations where a structured API is not available, make sure that you escape quotes before embedding
user-provided data into a quoted string. For example, this is how you can backslash-escape single
quotes using <code>strings.ReplaceAll</code>:
</p>
<sample language="go">
quoted := strings.ReplaceAll(raw, `\`, `\\`)
quoted = strings.ReplaceAll(quoted, "'", "\\'")
</sample>
<p>
Note that any existing backslash characters in the string must be escaped first, so that they do
not interfere with the escaping of single quotes.
</p>
<p>
In some cases, <code>strconv.Quote</code> is a convenient option for backslash escaping, but note
that it has two limitations:
</p>
<ol>
<li>It only supports double quotes, not single quotes (as in the example).</li>
<li>It puts quotes around the entire string, so it can only be used to construct complete string
literals, not parts of larger string literals.</li>
</ol>
</example>
<references>

View File

@@ -49,6 +49,15 @@ predicate gapInChildren(Element e, int i) {
not e instanceof Annotation and
// Pattern case statements legitimately have a TypeAccess (-2) and a pattern (0) but not a rule (-1)
not (i = -1 and e instanceof PatternCase and not e.(PatternCase).isRule()) and
// Pattern case statements can have a gap at -3 when they have more than one pattern but no guard.
not (
i = -3 and count(e.(PatternCase).getAPattern()) > 1 and not exists(e.(PatternCase).getGuard())
) and
// Pattern case statements may have some missing type accesses, depending on the nature of the direct child
not (
(i = -2 or i < -4) and
e instanceof PatternCase
) and
// Instanceof with a record pattern is not expected to have a type access in position 1
not (i = 1 and e.(InstanceOfExpr).getPattern() instanceof RecordPatternExpr) and
// RecordPatternExpr extracts type-accesses only for its LocalVariableDeclExpr children

View File

@@ -1,6 +1,6 @@
extensions:
- addsTo:
pack: integrationtest-default-parameter-mad-flow
pack: codeql/java-all
extensible: summaryModel
data:
- ["", "ConstructorWithDefaults", True, "ConstructorWithDefaults", "(int,int)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
@@ -11,14 +11,14 @@ extensions:
- ["", "LibClass", True, "multiParameterTest", "(int,int,int,int)", "", "Argument[0..1]", "ReturnValue", "value", "manual"]
- ["", "LibClass", True, "multiParameterExtensionTest", "(int,int,int,int)", "", "Argument[0, 1]", "ReturnValue", "value", "manual"]
- addsTo:
pack: integrationtest-default-parameter-mad-flow
pack: codeql/java-all
extensible: sourceModel
data:
- ["", "LibKt", True, "topLevelArgSource", "(SomeToken,int)", "", "Argument[0]", "kotlinMadFlowTest", "manual"]
- ["", "LibKt", True, "extensionArgSource", "(String,SomeToken,int)", "", "Argument[1]", "kotlinMadFlowTest", "manual"]
- ["", "SourceClass", True, "memberArgSource", "(SomeToken,int)", "", "Argument[0]", "kotlinMadFlowTest", "manual"]
- addsTo:
pack: integrationtest-default-parameter-mad-flow
pack: codeql/java-all
extensible: sinkModel
data:
- ["", "SinkClass", True, "SinkClass", "(int,int)", "", "Argument[0]", "kotlinMadFlowTest", "manual"]

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* The Java extractor and QL libraries now support Java 22, including support for anonymous variables, lambda parameters and patterns.
* Pattern cases with multiple patterns and that fall through to or from other pattern cases are now supported. The `PatternCase` class gains the new `getPatternAtIndex` and `getAPattern` predicates, and deprecates `getPattern`.

View File

@@ -489,14 +489,14 @@ private module ControlFlowGraphImpl {
private Stmt getSwitchStatement(SwitchBlock switch, int i) { result.isNthChildOf(switch, i) }
/**
* Holds if `last` is the last node in a pattern case `pc`'s succeeding bind-and-test operation,
* Holds if `last` is the last node in any of pattern case `pc`'s succeeding bind-and-test operations,
* immediately before either falling through to execute successor statements or execute a rule body
* if present. `completion` is the completion kind of the last operation.
*/
private predicate lastPatternCaseMatchingOp(
PatternCase pc, ControlFlowNode last, Completion completion
) {
last(pc.getPattern(), last, completion) and
last(pc.getAPattern(), last, completion) and
completion = NormalCompletion() and
not exists(pc.getGuard())
or
@@ -776,6 +776,18 @@ private module ControlFlowGraphImpl {
last(try.getFinally(), last, NormalCompletion())
}
private predicate isNextNormalSwitchStmt(SwitchBlock switch, Stmt pred, Stmt succ) {
exists(int i, Stmt immediateSucc |
getSwitchStatement(switch, i) = pred and
getSwitchStatement(switch, i + 1) = immediateSucc and
(
if immediateSucc instanceof PatternCase
then isNextNormalSwitchStmt(switch, immediateSucc, succ)
else succ = immediateSucc
)
)
}
/**
* Bind `last` to a cfg node nested inside `n` (or, indeed, `n` itself) such
* that `last` may be the last node during an execution of `n` and finish
@@ -927,9 +939,15 @@ private module ControlFlowGraphImpl {
completion != anonymousBreakCompletion() and
not completion instanceof NormalOrBooleanCompletion
or
// if the last case completes normally, then so does the switch
last(switch.getStmt(strictcount(switch.getAStmt()) - 1), last, NormalCompletion()) and
completion = NormalCompletion()
// if a statement without a non-pattern-case successor completes normally (or for a pattern case
// the guard succeeds) then the switch completes normally.
exists(Stmt lastNormalStmt, Completion stmtCompletion |
lastNormalStmt = getSwitchStatement(switch, _) and
not isNextNormalSwitchStmt(switch, lastNormalStmt, _) and
last(lastNormalStmt, last, stmtCompletion) and
(stmtCompletion = NormalCompletion() or stmtCompletion = BooleanCompletion(true, _)) and
completion = NormalCompletion()
)
or
// if no default case exists, then normal completion of the expression may terminate the switch
// Note this can't happen if there are pattern cases or a null literal, as
@@ -973,9 +991,9 @@ private module ControlFlowGraphImpl {
)
or
// A pattern case statement can complete:
// * On failure of its type test (boolean false)
// * On failure of its final type test (boolean false)
// * On failure of its guard test if any (boolean false)
// * On completion of its variable declarations, if it is not a rule and has no guard (normal completion)
// * On completion of one of its pattern variable declarations, if it is not a rule and has no guard (normal completion)
// * On success of its guard test, if it is not a rule (boolean true)
// (the latter two cases are accounted for by lastPatternCaseMatchingOp)
exists(PatternCase pc | n = pc |
@@ -1315,9 +1333,13 @@ private module ControlFlowGraphImpl {
// Note this includes non-rule case statements and the successful pattern match successor
// of a non-rule pattern case statement. Rule case statements do not complete normally
// (they always break or yield).
exists(int i |
last(getSwitchStatement(switch, i), n, completion) and
result = first(getSwitchStatement(switch, i + 1)) and
// Exception: falling through into a pattern case statement (which necessarily does not
// declare any named variables) must skip one or more such statements, otherwise we would
// incorrectly apply their type test and/or guard.
exists(Stmt pred, Stmt succ |
isNextNormalSwitchStmt(switch, pred, succ) and
last(pred, n, completion) and
result = first(succ) and
(completion = NormalCompletion() or completion = BooleanCompletion(true, _))
)
or
@@ -1328,16 +1350,19 @@ private module ControlFlowGraphImpl {
)
or
// Pattern cases have internal edges:
// * Type test success -true-> variable declarations
// * Type test success -true-> one of the possible sets of variable declarations
// n.b. for unnamed patterns (e.g. case A _, B _) this means that *one* of the
// type tests has succeeded. There aren't enough nodes in the AST to describe
// a sequential test in detail, so CFG consumers have to watch out for this case.
// * Variable declarations -normal-> guard evaluation
// * Variable declarations -normal-> rule execution (when there is no guard)
// * Guard success -true-> rule execution
exists(PatternCase pc |
n = pc and
completion = basicBooleanCompletion(true) and
result = first(pc.getPattern())
result = first(pc.getAPattern())
or
last(pc.getPattern(), n, completion) and
last(pc.getAPattern(), n, completion) and
completion = NormalCompletion() and
result = first(pc.getGuard())
or

View File

@@ -84,7 +84,7 @@ predicate depends(RefType t, RefType dep) {
or
// A type accessed in a pattern-switch case statement in `t`.
exists(PatternCase pc | t = pc.getEnclosingCallable().getDeclaringType() |
usesType(pc.getPattern().getAChildExpr*().getType(), dep)
usesType(pc.getAPattern().getAChildExpr*().getType(), dep)
)
)
}

View File

@@ -107,7 +107,7 @@ predicate numDepends(RefType t, RefType dep, int value) {
or
// the type accessed in a pattern-switch case statement in `t`.
exists(PatternCase pc | elem = pc and t = pc.getEnclosingCallable().getDeclaringType() |
usesType(pc.getPattern().getAChildExpr*().getType(), dep)
usesType(pc.getAPattern().getAChildExpr*().getType(), dep)
)
)
}

View File

@@ -1590,7 +1590,9 @@ class InstanceOfExpr extends Expr, @instanceofexpr {
* Note that this won't get anything when record pattern matching is used-- for more general patterns,
* use `getPattern`.
*/
LocalVariableDeclExpr getLocalVariableDeclExpr() { result = this.getPattern().asBindingPattern() }
LocalVariableDeclExpr getLocalVariableDeclExpr() {
result = this.getPattern().asBindingOrUnnamedPattern()
}
/**
* Gets the access to the type on the right-hand side of the `instanceof` operator.
@@ -1681,7 +1683,10 @@ class LocalVariableDeclExpr extends Expr, @localvariabledeclexpr {
or
exists(InstanceOfExpr ioe | this.getParent() = ioe | result.isNthChildOf(ioe, 1))
or
exists(PatternCase pc | this.getParent() = pc | result.isNthChildOf(pc, -2))
exists(PatternCase pc, int index, int typeAccessIdx | this.isNthChildOf(pc, index) |
(if index = 0 then typeAccessIdx = -2 else typeAccessIdx = (-3 - index)) and
result.isNthChildOf(pc, typeAccessIdx)
)
or
exists(RecordPatternExpr rpe, int index |
this.isNthChildOf(rpe, index) and result.isNthChildOf(rpe, -(index + 1))
@@ -1691,6 +1696,9 @@ class LocalVariableDeclExpr extends Expr, @localvariabledeclexpr {
/** Gets the name of the variable declared by this local variable declaration expression. */
string getName() { result = this.getVariable().getName() }
/** Holds if this is an anonymous local variable, `_` */
predicate isAnonymous() { this.getName() = "" }
/**
* Gets the switch statement or expression whose pattern declares this identifier, if any.
*/
@@ -1700,7 +1708,7 @@ class LocalVariableDeclExpr extends Expr, @localvariabledeclexpr {
or
pc = result.(SwitchExpr).getAPatternCase()
|
this = pc.getPattern().getAChildExpr*()
this = pc.getAPattern().getAChildExpr*()
)
}
@@ -1739,17 +1747,17 @@ class LocalVariableDeclExpr extends Expr, @localvariabledeclexpr {
or
exists(SwitchStmt switch |
result = switch.getExpr() and
this = switch.getAPatternCase().getPattern().asBindingPattern()
this = switch.getAPatternCase().getAPattern().asBindingOrUnnamedPattern()
)
or
exists(SwitchExpr switch |
result = switch.getExpr() and
this = switch.getAPatternCase().getPattern().asBindingPattern()
this = switch.getAPatternCase().getAPattern().asBindingOrUnnamedPattern()
)
or
exists(InstanceOfExpr ioe |
result = ioe.getExpr() and
this = ioe.getPattern().asBindingPattern()
this = ioe.getPattern().asBindingOrUnnamedPattern()
)
}
@@ -1763,7 +1771,9 @@ class LocalVariableDeclExpr extends Expr, @localvariabledeclexpr {
}
/** Gets a printable representation of this expression. */
override string toString() { result = this.getName() }
override string toString() {
if this.getName() = "" then result = "<anonymous local variable>" else result = this.getName()
}
override string getAPrimaryQlClass() { result = "LocalVariableDeclExpr" }
}
@@ -2671,9 +2681,9 @@ class NotNullExpr extends UnaryExpr, @notnullexpr {
}
/**
* A binding or record pattern.
* A binding, unnamed or record pattern.
*
* Note binding patterns are represented as `LocalVariableDeclExpr`s.
* Note binding and unnamed patterns are represented as `LocalVariableDeclExpr`s.
*/
class PatternExpr extends Expr {
PatternExpr() {
@@ -2686,9 +2696,14 @@ class PatternExpr extends Expr {
}
/**
* Gets this pattern cast to a binding pattern.
* Gets this pattern cast to a binding or unnamed pattern.
*/
LocalVariableDeclExpr asBindingPattern() { result = this }
LocalVariableDeclExpr asBindingOrUnnamedPattern() { result = this }
/**
* DEPRECATED: alias for `asBindingOrUnnamedPattern`.
*/
deprecated LocalVariableDeclExpr asBindingPattern() { result = this.asBindingOrUnnamedPattern() }
/**
* Gets this pattern cast to a record pattern.
@@ -2724,4 +2739,14 @@ class RecordPatternExpr extends Expr, @recordpatternexpr {
)
)
}
/**
* Holds if this record pattern declares any identifiers (i.e., at least one leaf declaration is named).
*/
predicate declaresAnyIdentifiers() {
exists(PatternExpr subPattern | subPattern = this.getSubPattern(_) |
subPattern.asRecordPattern().declaresAnyIdentifiers() or
not subPattern.asBindingOrUnnamedPattern().isAnonymous()
)
}
}

View File

@@ -386,7 +386,7 @@ private class PpInstanceOfExpr extends PpAst, InstanceOfExpr {
i = 3 and result = " " and this.getPattern() instanceof LocalVariableDeclExpr
or
i = 4 and
result = this.getPattern().asBindingPattern().getName()
result = this.getPattern().asBindingOrUnnamedPattern().getName()
}
override PpAst getChild(int i) {
@@ -400,7 +400,8 @@ private class PpInstanceOfExpr extends PpAst, InstanceOfExpr {
private class PpLocalVariableDeclExpr extends PpAst, LocalVariableDeclExpr {
override string getPart(int i) {
i = 0 and result = this.getName()
i = 0 and
(if this.isAnonymous() then result = "_" else result = this.getName())
or
i = 1 and result = " = " and exists(this.getInit())
}
@@ -782,28 +783,54 @@ private class PpSwitchCase extends PpAst, SwitchCase {
}
private class PpPatternCase extends PpAst, PatternCase {
private predicate isAnonymousPattern(int n) {
this.getPattern(n).asBindingOrUnnamedPattern().isAnonymous()
}
override string getPart(int i) {
i = 0 and result = "case "
exists(int n, int base | exists(this.getPattern(n)) and base = n * 4 |
i = base and
(if n = 0 then result = "case " else result = ", ")
or
i = base + 2 and
this.getPattern(n) instanceof LocalVariableDeclExpr and
(
exists(this.getPattern(n).asBindingOrUnnamedPattern().getTypeAccess())
or
not this.isAnonymousPattern(n)
) and
result = " "
or
i = base + 3 and
(
if this.isAnonymousPattern(n)
then result = "_"
else result = this.getPattern(n).asBindingOrUnnamedPattern().getName()
)
)
or
i = 2 and this.getPattern() instanceof LocalVariableDeclExpr and result = " "
or
i = 3 and result = this.getPattern().asBindingPattern().getName()
or
i = 4 and result = ":" and not this.isRule()
or
i = 4 and result = " -> " and this.isRule()
or
i = 6 and result = ";" and exists(this.getRuleExpression())
exists(int base | base = (max(int n | exists(this.getPattern(n))) + 1) * 4 |
i = base and result = ":" and not this.isRule()
or
i = base and result = " -> " and this.isRule()
or
i = base + 2 and result = ";" and exists(this.getRuleExpression())
)
}
override PpAst getChild(int i) {
i = 1 and result = this.getPattern().asBindingPattern().getTypeAccess()
exists(int n, int base | exists(this.getPattern(n)) and base = n * 4 |
i = base + 1 and
result = this.getPattern(n).asBindingOrUnnamedPattern().getTypeAccess()
or
i = base + 1 and result = this.getPattern(n).asRecordPattern()
)
or
i = 1 and result = this.getPattern().asRecordPattern()
or
i = 5 and result = this.getRuleExpression()
or
i = 5 and result = this.getRuleStatement()
exists(int base | base = (max(int n | exists(this.getPattern(n))) + 1) * 4 |
i = base + 1 and result = this.getRuleExpression()
or
i = base + 1 and result = this.getRuleStatement()
)
}
}

View File

@@ -117,7 +117,11 @@ private newtype TPrintAstNode =
TElementNode(Element el) { shouldPrint(el, _) } or
TForInitNode(ForStmt fs) { shouldPrint(fs, _) and exists(fs.getAnInit()) } or
TLocalVarDeclNode(LocalVariableDeclExpr lvde) {
shouldPrint(lvde, _) and lvde.getParent() instanceof SingleLocalVarDeclParent
shouldPrint(lvde, _) and
(
lvde.getParent() instanceof SingleLocalVarDeclParent or
lvde.getParent() instanceof PatternCase
)
} or
TAnnotationsNode(Annotatable ann) {
shouldPrint(ann, _) and
@@ -415,6 +419,23 @@ final class ForStmtNode extends ExprStmtNode {
}
}
/**
* A node representing a `PatternCase`.
*/
final class PatternCaseNode extends ExprStmtNode {
PatternCase pc;
PatternCaseNode() { pc = element }
override PrintAstNode getChild(int childIndex) {
result = super.getChild(childIndex) and
not result.(ElementNode).getElement() instanceof LocalVariableDeclExpr and
not result.(ElementNode).getElement() instanceof TypeAccess
or
result = TLocalVarDeclNode(pc.getPattern(childIndex))
}
}
/**
* An element that can be the parent of up to one `LocalVariableDeclExpr` for which we want
* to use a synthetic node to hold the variable declaration and its `TypeAccess`.
@@ -423,8 +444,7 @@ private class SingleLocalVarDeclParent extends ExprOrStmt {
SingleLocalVarDeclParent() {
this instanceof EnhancedForStmt or
this instanceof CatchClause or
this.(InstanceOfExpr).isPattern() or
this instanceof PatternCase
this.(InstanceOfExpr).isPattern()
}
/** Gets the variable declaration that this element contains */
@@ -439,7 +459,7 @@ private class SingleLocalVarDeclParent extends ExprOrStmt {
* want to use a synthetic node to variable declaration and its type access.
*
* Excludes `LocalVariableDeclStmt` and `ForStmt`, as they can hold multiple declarations.
* For these cases, either a synthetic node is not necassary or a different synthetic node is used.
* For these cases, either a synthetic node is not necessary or a different synthetic node is used.
*/
final class SingleLocalVarDeclParentNode extends ExprStmtNode {
SingleLocalVarDeclParent lvdp;
@@ -643,7 +663,11 @@ final class LocalVarDeclSynthNode extends PrintAstNode, TLocalVarDeclNode {
LocalVarDeclSynthNode() { this = TLocalVarDeclNode(lvde) }
override string toString() { result = "(Single Local Variable Declaration)" }
override string toString() {
if lvde.getParent() instanceof PatternCase
then result = "(Pattern case declaration)"
else result = "(Single Local Variable Declaration)"
}
override ElementNode getChild(int childIndex) {
childIndex = 0 and

View File

@@ -539,12 +539,27 @@ class ConstCase extends SwitchCase {
/** A pattern case of a `switch` statement */
class PatternCase extends SwitchCase {
PatternExpr pattern;
PatternCase() { exists(PatternExpr pe | pe.isNthChildOf(this, _)) }
PatternCase() { pattern.isNthChildOf(this, 0) }
/**
* DEPRECATED: alias for getPattern(0)
*/
deprecated PatternExpr getPattern() { result = this.getPattern(0) }
/** Gets this case's pattern. */
PatternExpr getPattern() { result = pattern }
/**
* Gets this case's `n`th pattern.
*/
PatternExpr getPattern(int n) { result.isNthChildOf(this, n) }
/**
* Gets any of this case's patterns.
*/
PatternExpr getAPattern() { result = this.getPattern(_) }
/**
* Gets this case's sole pattern, if there is exactly one.
*/
PatternExpr getUniquePattern() { result = unique(PatternExpr pe | pe = this.getAPattern()) }
/** Gets the guard applicable to this pattern case, if any. */
Expr getGuard() { result.isNthChildOf(this, -3) }

View File

@@ -58,7 +58,13 @@ class LocalVariableDecl extends @localvar, LocalScopeVariable {
/** Gets the callable in which this declaration occurs. */
Callable getEnclosingCallable() { result = this.getCallable() }
override string toString() { result = this.getType().getName() + " " + this.getName() }
override string toString() {
exists(string sourceName |
if this.getName() = "" then sourceName = "_" else sourceName = this.getName()
|
result = this.getType().getName() + " " + sourceName
)
}
/** Gets the initializer expression of this local variable declaration. */
override Expr getInitializer() { result = this.getDeclExpr().getInit() }
@@ -117,4 +123,11 @@ class Parameter extends Element, @param, LocalScopeVariable {
}
override string getAPrimaryQlClass() { result = "Parameter" }
override string toString() {
if this.getName() = "" then result = "<anonymous parameter>" else result = super.toString()
}
/** Holds if this is an anonymous parameter, `_` */
predicate isAnonymous() { this.getName() = "" }
}

View File

@@ -115,8 +115,24 @@ private predicate isNonFallThroughPredecessor(SwitchCase sc, ControlFlowNode pre
(
pred.(Expr).getParent*() = sc.getSelectorExpr()
or
pred.(Expr).getParent*() = getClosestPrecedingPatternCase(sc).getGuard()
// Ambiguous: in the case of `case String _ when x: case "SomeConstant":`, the guard `x`
// passing edge will fall through into the constant case, and the guard failing edge
// will test if the selector equals `"SomeConstant"` and if so branch to the same
// case statement. Therefore don't label this a non-fall-through predecessor.
exists(PatternCase previousPatternCase |
previousPatternCase = getClosestPrecedingPatternCase(sc)
|
pred.(Expr).getParent*() = previousPatternCase.getGuard() and
// Check there is any statement in between the previous pattern case and this one,
// or the case is a rule, so there is no chance of a fall-through.
(
previousPatternCase.isRule() or
not previousPatternCase.getIndex() = sc.getIndex() - 1
)
)
or
// Unambigious: on the test-passing edge there must be at least one intervening
// declaration node, including anonymous `_` declarations.
pred = getClosestPrecedingPatternCase(sc)
)
}
@@ -201,13 +217,13 @@ class Guard extends ExprParent {
or
exists(PatternCase pc | this = pc |
pc.getSelectorExpr() = testedExpr and
testedType = pc.getPattern().getType()
testedType = pc.getUniquePattern().getType()
)
) and
(
if
exists(RecordPatternExpr rpe |
rpe = [this.(InstanceOfExpr).getPattern(), this.(PatternCase).getPattern()]
rpe = [this.(InstanceOfExpr).getPattern(), this.(PatternCase).getAPattern()]
|
not rpe.isUnrestricted()
)

View File

@@ -194,12 +194,17 @@ predicate simpleAstFlowStep(Expr e1, Expr e2) {
// In the following three cases only record patterns need this flow edge, leading from the bound instanceof
// or switch tested expression to a record pattern that will read its fields. Simple binding patterns are
// handled via VariableAssign.getSource instead.
exists(SwitchExpr se |
e1 = se.getExpr() and e2 = se.getACase().(PatternCase).getPattern().asRecordPattern()
// We only consider patterns that declare any identifiers
exists(SwitchExpr se, RecordPatternExpr recordPattern | recordPattern = e2 |
e1 = se.getExpr() and
recordPattern = se.getACase().(PatternCase).getAPattern() and
recordPattern.declaresAnyIdentifiers()
)
or
exists(SwitchStmt ss |
e1 = ss.getExpr() and e2 = ss.getACase().(PatternCase).getPattern().asRecordPattern()
exists(SwitchStmt ss, RecordPatternExpr recordPattern | recordPattern = e2 |
e1 = ss.getExpr() and
recordPattern = ss.getACase().(PatternCase).getAPattern() and
recordPattern.declaresAnyIdentifiers()
)
or
exists(InstanceOfExpr ioe | e1 = ioe.getExpr() and e2 = ioe.getPattern().asRecordPattern())

View File

@@ -1,10 +1,5 @@
extensions:
- addsTo:
pack: codeql/java-all
extensible: supportedThreatModels
data: []
- addsTo:
pack: codeql/java-all
extensible: sourceModel

View File

@@ -63,7 +63,7 @@ dependency/A.java:
# 31| 1: [SwitchStmt] switch (...)
# 31| -1: [VarAccess] o
# 32| 0: [PatternCase] case <Pattern>
#-----| 0: (Single Local Variable Declaration)
#-----| 0: (Pattern case declaration)
# 32| 0: [TypeAccess] Used2
# 32| 1: [LocalVariableDeclExpr] u2
# 32| 1: [BreakStmt] break
@@ -74,7 +74,7 @@ dependency/A.java:
# 35| 0: [SwitchExpr] switch (...)
# 35| -1: [VarAccess] o
# 36| 0: [PatternCase] case <Pattern>
#-----| 0: (Single Local Variable Declaration)
#-----| 0: (Pattern case declaration)
# 36| 0: [TypeAccess] Used3
# 36| 1: [LocalVariableDeclExpr] u3
# 36| 1: [YieldStmt] yield ...

View File

@@ -52,9 +52,9 @@ Test.java:
# 17| 0: [VarAccess] len
# 17| 1: [IntegerLiteral] 4
# 17| -1: [BlockStmt] { ... }
#-----| 0: (Single Local Variable Declaration)
#-----| 0: (Pattern case declaration)
# 17| 0: [TypeAccess] String
# 17| 1: [LocalVariableDeclExpr] s2
# 17| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 18| 1: [ConstCase] case ...
# 18| -1: [BlockStmt] { ... }
# 18| 0: [StringLiteral] "e"
@@ -74,7 +74,7 @@ Test.java:
# 23| 0: [VarAccess] len
# 23| 1: [IntegerLiteral] 4
# 23| -1: [BlockStmt] { ... }
#-----| 0: (Single Local Variable Declaration)
#-----| 0: (Pattern case declaration)
# 23| 0: [TypeAccess] String
# 23| 1: [LocalVariableDeclExpr] s2
# 24| 2: [ConstCase] case ...
@@ -82,3 +82,23 @@ Test.java:
# 24| 0: [StringLiteral] "g"
# 25| 3: [DefaultCase] default
# 25| -1: [BlockStmt] { ... }
# 27| 5: [SwitchStmt] switch (...)
# 27| -1: [VarAccess] s
# 28| 0: [ConstCase] case ...
# 28| 0: [StringLiteral] "h"
# 29| 1: [PatternCase] case <Pattern>
# 29| -3: [EQExpr] ... == ...
# 29| 0: [VarAccess] len
# 29| 1: [IntegerLiteral] 4
#-----| 0: (Pattern case declaration)
# 29| 0: [TypeAccess] String
# 29| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 30| 2: [ConstCase] case ...
# 30| 0: [StringLiteral] "i"
# 31| 3: [LocalVariableDeclStmt] var ...;
# 31| 0: [TypeAccess] String
# 31| 1: [LocalVariableDeclExpr] target
# 31| 0: [StringLiteral] "Shouldn't be controlled by any of those tests"
# 32| 4: [BreakStmt] break
# 33| 5: [DefaultCase] default
# 34| 6: [BreakStmt] break

View File

@@ -14,7 +14,7 @@ class Test {
}
int len = s.length();
switch (s) {
case String s2 when len == 4 -> { }
case String _ when len == 4 -> { }
case "e" -> { }
default -> { }
}
@@ -24,5 +24,14 @@ class Test {
case "g" -> { }
default -> { }
}
switch (s) {
case "h":
case String _ when len == 4:
case "i":
String target = "Shouldn't be controlled by any of those tests";
break;
default:
break;
}
}
}

View File

@@ -1,22 +1,22 @@
hasBranchEdge
| Test.java:4:7:4:22 | case ... | Test.java:2:39:27:3 | { ... } | Test.java:4:7:4:22 | case ... | true |
| Test.java:5:7:5:17 | case ... | Test.java:2:39:27:3 | { ... } | Test.java:5:7:5:17 | case ... | true |
| Test.java:6:7:6:17 | case ... | Test.java:2:39:27:3 | { ... } | Test.java:6:7:6:17 | case ... | true |
| Test.java:7:7:7:16 | default | Test.java:2:39:27:3 | { ... } | Test.java:7:7:7:16 | default | true |
| Test.java:4:7:4:22 | case ... | Test.java:2:39:36:3 | { ... } | Test.java:4:7:4:22 | case ... | true |
| Test.java:5:7:5:17 | case ... | Test.java:2:39:36:3 | { ... } | Test.java:5:7:5:17 | case ... | true |
| Test.java:6:7:6:17 | case ... | Test.java:2:39:36:3 | { ... } | Test.java:6:7:6:17 | case ... | true |
| Test.java:7:7:7:16 | default | Test.java:2:39:36:3 | { ... } | Test.java:7:7:7:16 | default | true |
| Test.java:10:7:10:22 | case ... | Test.java:3:9:3:21 | x | Test.java:10:7:10:22 | case ... | true |
| Test.java:11:7:11:17 | case ... | Test.java:3:9:3:21 | x | Test.java:11:7:11:17 | case ... | true |
| Test.java:12:7:12:17 | case ... | Test.java:3:9:3:21 | x | Test.java:12:7:12:17 | case ... | true |
| Test.java:13:7:13:16 | default | Test.java:3:9:3:21 | x | Test.java:13:7:13:16 | default | true |
| Test.java:17:7:17:37 | case <Pattern> | Test.java:15:5:15:25 | var ...; | Test.java:17:19:17:20 | s2 | true |
| Test.java:17:7:17:37 | case <Pattern> | Test.java:15:5:15:25 | var ...; | Test.java:18:7:18:17 | case ... | false |
| Test.java:17:7:17:37 | case <Pattern> | Test.java:15:5:15:25 | var ...; | Test.java:19:7:19:16 | default | false |
| Test.java:17:27:17:34 | ... == ... | Test.java:17:19:17:20 | s2 | Test.java:17:39:17:41 | { ... } | true |
| Test.java:17:27:17:34 | ... == ... | Test.java:17:19:17:20 | s2 | Test.java:18:7:18:17 | case ... | false |
| Test.java:17:27:17:34 | ... == ... | Test.java:17:19:17:20 | s2 | Test.java:19:7:19:16 | default | false |
| Test.java:17:7:17:36 | case <Pattern> | Test.java:15:5:15:25 | var ...; | Test.java:17:19:17:19 | <anonymous local variable> | true |
| Test.java:17:7:17:36 | case <Pattern> | Test.java:15:5:15:25 | var ...; | Test.java:18:7:18:17 | case ... | false |
| Test.java:17:7:17:36 | case <Pattern> | Test.java:15:5:15:25 | var ...; | Test.java:19:7:19:16 | default | false |
| Test.java:17:26:17:33 | ... == ... | Test.java:17:19:17:19 | <anonymous local variable> | Test.java:17:38:17:40 | { ... } | true |
| Test.java:17:26:17:33 | ... == ... | Test.java:17:19:17:19 | <anonymous local variable> | Test.java:18:7:18:17 | case ... | false |
| Test.java:17:26:17:33 | ... == ... | Test.java:17:19:17:19 | <anonymous local variable> | Test.java:19:7:19:16 | default | false |
| Test.java:18:7:18:17 | case ... | Test.java:15:5:15:25 | var ...; | Test.java:18:7:18:17 | case ... | true |
| Test.java:18:7:18:17 | case ... | Test.java:17:19:17:20 | s2 | Test.java:18:7:18:17 | case ... | true |
| Test.java:18:7:18:17 | case ... | Test.java:17:19:17:19 | <anonymous local variable> | Test.java:18:7:18:17 | case ... | true |
| Test.java:19:7:19:16 | default | Test.java:15:5:15:25 | var ...; | Test.java:19:7:19:16 | default | true |
| Test.java:19:7:19:16 | default | Test.java:17:19:17:20 | s2 | Test.java:19:7:19:16 | default | true |
| Test.java:19:7:19:16 | default | Test.java:17:19:17:19 | <anonymous local variable> | Test.java:19:7:19:16 | default | true |
| Test.java:21:13:21:19 | unknown | Test.java:21:5:21:42 | switch (...) | Test.java:21:23:21:23 | s | true |
| Test.java:21:13:21:19 | unknown | Test.java:21:5:21:42 | switch (...) | Test.java:21:27:21:27 | s | false |
| Test.java:22:7:22:17 | case ... | Test.java:21:23:21:23 | s | Test.java:22:7:22:17 | case ... | true |
@@ -31,6 +31,16 @@ hasBranchEdge
| Test.java:24:7:24:17 | case ... | Test.java:23:19:23:20 | s2 | Test.java:24:7:24:17 | case ... | true |
| Test.java:25:7:25:16 | default | Test.java:23:7:23:37 | case <Pattern> | Test.java:25:7:25:16 | default | true |
| Test.java:25:7:25:16 | default | Test.java:23:19:23:20 | s2 | Test.java:25:7:25:16 | default | true |
| Test.java:28:7:28:15 | case ... | Test.java:27:5:27:14 | switch (...) | Test.java:28:7:28:15 | case ... | true |
| Test.java:29:7:29:34 | case <Pattern> | Test.java:29:7:29:34 | case <Pattern> | Test.java:29:19:29:19 | <anonymous local variable> | true |
| Test.java:29:7:29:34 | case <Pattern> | Test.java:29:7:29:34 | case <Pattern> | Test.java:30:7:30:15 | case ... | false |
| Test.java:29:7:29:34 | case <Pattern> | Test.java:29:7:29:34 | case <Pattern> | Test.java:33:7:33:14 | default | false |
| Test.java:29:26:29:33 | ... == ... | Test.java:29:19:29:19 | <anonymous local variable> | Test.java:30:7:30:15 | case ... | false |
| Test.java:29:26:29:33 | ... == ... | Test.java:29:19:29:19 | <anonymous local variable> | Test.java:30:7:30:15 | case ... | true |
| Test.java:29:26:29:33 | ... == ... | Test.java:29:19:29:19 | <anonymous local variable> | Test.java:33:7:33:14 | default | false |
| Test.java:30:7:30:15 | case ... | Test.java:29:7:29:34 | case <Pattern> | Test.java:30:7:30:15 | case ... | true |
| Test.java:33:7:33:14 | default | Test.java:29:7:29:34 | case <Pattern> | Test.java:33:7:33:14 | default | true |
| Test.java:33:7:33:14 | default | Test.java:29:19:29:19 | <anonymous local variable> | Test.java:33:7:33:14 | default | true |
#select
| Test.java:5:7:5:17 | case ... | Test.java:3:20:3:20 | s | Test.java:5:12:5:14 | "c" | true | false | Test.java:7:7:7:16 | default |
| Test.java:5:7:5:17 | case ... | Test.java:3:20:3:20 | s | Test.java:5:12:5:14 | "c" | true | true | Test.java:5:7:5:17 | case ... |
@@ -40,7 +50,7 @@ hasBranchEdge
| Test.java:11:7:11:17 | case ... | Test.java:9:13:9:13 | s | Test.java:11:12:11:14 | "c" | true | true | Test.java:11:7:11:17 | case ... |
| Test.java:12:7:12:17 | case ... | Test.java:9:13:9:13 | s | Test.java:12:12:12:14 | "d" | true | false | Test.java:13:7:13:16 | default |
| Test.java:12:7:12:17 | case ... | Test.java:9:13:9:13 | s | Test.java:12:12:12:14 | "d" | true | true | Test.java:12:7:12:17 | case ... |
| Test.java:17:27:17:34 | ... == ... | Test.java:17:27:17:29 | len | Test.java:17:34:17:34 | 4 | true | true | Test.java:17:39:17:41 | { ... } |
| Test.java:17:26:17:33 | ... == ... | Test.java:17:26:17:28 | len | Test.java:17:33:17:33 | 4 | true | true | Test.java:17:38:17:40 | { ... } |
| Test.java:18:7:18:17 | case ... | Test.java:16:13:16:13 | s | Test.java:18:12:18:14 | "e" | true | false | Test.java:19:7:19:16 | default |
| Test.java:18:7:18:17 | case ... | Test.java:16:13:16:13 | s | Test.java:18:12:18:14 | "e" | true | true | Test.java:18:7:18:17 | case ... |
| Test.java:22:7:22:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:22:12:22:14 | "f" | true | false | Test.java:25:7:25:16 | default |
@@ -48,3 +58,6 @@ hasBranchEdge
| Test.java:23:27:23:34 | ... == ... | Test.java:23:27:23:29 | len | Test.java:23:34:23:34 | 4 | true | true | Test.java:23:39:23:41 | { ... } |
| Test.java:24:7:24:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:24:12:24:14 | "g" | true | false | Test.java:25:7:25:16 | default |
| Test.java:24:7:24:17 | case ... | Test.java:21:13:21:41 | ...?...:... | Test.java:24:12:24:14 | "g" | true | true | Test.java:24:7:24:17 | case ... |
| Test.java:28:7:28:15 | case ... | Test.java:27:13:27:13 | s | Test.java:28:12:28:14 | "h" | true | false | Test.java:33:7:33:14 | default |
| Test.java:28:7:28:15 | case ... | Test.java:27:13:27:13 | s | Test.java:28:12:28:14 | "h" | true | true | Test.java:28:7:28:15 | case ... |
| Test.java:30:7:30:15 | case ... | Test.java:27:13:27:13 | s | Test.java:30:12:30:14 | "i" | true | false | Test.java:33:7:33:14 | default |

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args --release 21
//semmle-extractor-options: --javac-args --release 22

View File

@@ -26,6 +26,12 @@ public class Exhaustive {
case Y y -> { }
}
// Test the case where a pattern case falls directly out of a block:
switch (i) {
case X _:
case Y _:
}
}
}

View File

@@ -98,6 +98,39 @@ public class Test {
break;
}
switch(thing) {
case B(_, _):
case Integer _, String _, A(_, _) when thing.toString().equals("abc"):
case Float _:
break;
default:
break;
}
var result = switch(thing) {
case B(_, _):
case Integer _, String _, A(_, _) when thing.toString().equals("abc"):
case Float _:
yield 1;
default:
yield 2;
};
switch ((String)thing) {
case "a":
case String _ when ((String)thing).length() == 5:
case "b":
break;
default:
break;
}
// Test the case where a case falls out of a switch block without a break:
switch(thing) {
case String _:
default:
}
}
}

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args --release 21
//semmle-extractor-options: --javac-args --release 22

View File

@@ -16,7 +16,7 @@
| Exhaustive.java:5:15:5:15 | { ... } | Exhaustive.java:5:15:5:15 | super(...) |
| Exhaustive.java:6:15:6:15 | super(...) | Exhaustive.java:6:15:6:15 | Y |
| Exhaustive.java:6:15:6:15 | { ... } | Exhaustive.java:6:15:6:15 | super(...) |
| Exhaustive.java:8:47:29:3 | { ... } | Exhaustive.java:11:5:11:14 | switch (...) |
| Exhaustive.java:8:47:35:3 | { ... } | Exhaustive.java:11:5:11:14 | switch (...) |
| Exhaustive.java:11:5:11:14 | switch (...) | Exhaustive.java:11:13:11:13 | o |
| Exhaustive.java:11:13:11:13 | o | Exhaustive.java:12:7:12:22 | case <Pattern> |
| Exhaustive.java:12:7:12:22 | case <Pattern> | Exhaustive.java:12:19:12:19 | s |
@@ -42,13 +42,20 @@
| Exhaustive.java:25:7:25:17 | case <Pattern> | Exhaustive.java:25:14:25:14 | x |
| Exhaustive.java:25:7:25:17 | case <Pattern> | Exhaustive.java:26:7:26:17 | case <Pattern> |
| Exhaustive.java:25:14:25:14 | x | Exhaustive.java:25:19:25:21 | { ... } |
| Exhaustive.java:25:19:25:21 | { ... } | Exhaustive.java:8:22:8:25 | test |
| Exhaustive.java:25:19:25:21 | { ... } | Exhaustive.java:30:5:30:14 | switch (...) |
| Exhaustive.java:26:7:26:17 | case <Pattern> | Exhaustive.java:26:14:26:14 | y |
| Exhaustive.java:26:14:26:14 | y | Exhaustive.java:26:19:26:21 | { ... } |
| Exhaustive.java:26:19:26:21 | { ... } | Exhaustive.java:8:22:8:25 | test |
| Exhaustive.java:26:19:26:21 | { ... } | Exhaustive.java:30:5:30:14 | switch (...) |
| Exhaustive.java:30:5:30:14 | switch (...) | Exhaustive.java:30:13:30:13 | i |
| Exhaustive.java:30:13:30:13 | i | Exhaustive.java:31:7:31:15 | case <Pattern> |
| Exhaustive.java:31:7:31:15 | case <Pattern> | Exhaustive.java:31:14:31:14 | <anonymous local variable> |
| Exhaustive.java:31:7:31:15 | case <Pattern> | Exhaustive.java:32:7:32:15 | case <Pattern> |
| Exhaustive.java:31:14:31:14 | <anonymous local variable> | Exhaustive.java:8:22:8:25 | test |
| Exhaustive.java:32:7:32:15 | case <Pattern> | Exhaustive.java:32:14:32:14 | <anonymous local variable> |
| Exhaustive.java:32:14:32:14 | <anonymous local variable> | Exhaustive.java:8:22:8:25 | test |
| Test.java:1:14:1:17 | super(...) | Test.java:1:14:1:17 | Test |
| Test.java:1:14:1:17 | { ... } | Test.java:1:14:1:17 | super(...) |
| Test.java:3:41:101:3 | { ... } | Test.java:5:6:5:19 | switch (...) |
| Test.java:3:41:134:3 | { ... } | Test.java:5:6:5:19 | switch (...) |
| Test.java:5:6:5:19 | switch (...) | Test.java:5:14:5:18 | thing |
| Test.java:5:14:5:18 | thing | Test.java:6:8:6:23 | case <Pattern> |
| Test.java:6:8:6:23 | case <Pattern> | Test.java:6:20:6:20 | s |
@@ -288,26 +295,109 @@
| Test.java:95:21:95:21 | x | Test.java:95:28:95:28 | y |
| Test.java:95:28:95:28 | y | Test.java:95:15:95:29 | B(...) |
| Test.java:95:36:95:36 | z | Test.java:95:13:95:37 | A(...) |
| Test.java:96:10:96:15 | break | Test.java:3:22:3:25 | test |
| Test.java:96:10:96:15 | break | Test.java:101:6:101:18 | switch (...) |
| Test.java:97:8:97:15 | default | Test.java:98:10:98:15 | break |
| Test.java:98:10:98:15 | break | Test.java:3:22:3:25 | test |
| Test.java:105:8:105:8 | ...=... | Test.java:105:8:105:8 | <Expr>; |
| Test.java:105:8:105:8 | ...=... | Test.java:105:8:105:8 | A |
| Test.java:105:8:105:8 | <Expr>; | Test.java:105:8:105:8 | this |
| Test.java:105:8:105:8 | <Expr>; | Test.java:105:8:105:8 | this |
| Test.java:105:8:105:8 | b | Test.java:105:8:105:8 | ...=... |
| Test.java:105:8:105:8 | field3 | Test.java:105:8:105:8 | ...=... |
| Test.java:105:8:105:8 | super(...) | Test.java:105:8:105:8 | <Expr>; |
| Test.java:105:8:105:8 | this | Test.java:105:8:105:8 | b |
| Test.java:105:8:105:8 | this | Test.java:105:8:105:8 | field3 |
| Test.java:105:8:105:8 | { ... } | Test.java:105:8:105:8 | super(...) |
| Test.java:106:8:106:8 | ...=... | Test.java:106:8:106:8 | <Expr>; |
| Test.java:106:8:106:8 | ...=... | Test.java:106:8:106:8 | B |
| Test.java:106:8:106:8 | <Expr>; | Test.java:106:8:106:8 | this |
| Test.java:106:8:106:8 | <Expr>; | Test.java:106:8:106:8 | this |
| Test.java:106:8:106:8 | field1 | Test.java:106:8:106:8 | ...=... |
| Test.java:106:8:106:8 | field2 | Test.java:106:8:106:8 | ...=... |
| Test.java:106:8:106:8 | super(...) | Test.java:106:8:106:8 | <Expr>; |
| Test.java:106:8:106:8 | this | Test.java:106:8:106:8 | field1 |
| Test.java:106:8:106:8 | this | Test.java:106:8:106:8 | field2 |
| Test.java:106:8:106:8 | { ... } | Test.java:106:8:106:8 | super(...) |
| Test.java:98:10:98:15 | break | Test.java:101:6:101:18 | switch (...) |
| Test.java:101:6:101:18 | switch (...) | Test.java:101:13:101:17 | thing |
| Test.java:101:13:101:17 | thing | Test.java:102:8:102:20 | case <Pattern> |
| Test.java:102:8:102:20 | case <Pattern> | Test.java:102:15:102:15 | <anonymous local variable> |
| Test.java:102:8:102:20 | case <Pattern> | Test.java:103:8:103:77 | case <Pattern> |
| Test.java:102:13:102:19 | B(...) | Test.java:105:10:105:15 | break |
| Test.java:102:15:102:15 | <anonymous local variable> | Test.java:102:18:102:18 | <anonymous local variable> |
| Test.java:102:18:102:18 | <anonymous local variable> | Test.java:102:13:102:19 | B(...) |
| Test.java:103:8:103:77 | case <Pattern> | Test.java:103:21:103:21 | <anonymous local variable> |
| Test.java:103:8:103:77 | case <Pattern> | Test.java:103:31:103:31 | <anonymous local variable> |
| Test.java:103:8:103:77 | case <Pattern> | Test.java:103:36:103:36 | <anonymous local variable> |
| Test.java:103:8:103:77 | case <Pattern> | Test.java:104:8:104:20 | case <Pattern> |
| Test.java:103:21:103:21 | <anonymous local variable> | Test.java:103:47:103:51 | thing |
| Test.java:103:31:103:31 | <anonymous local variable> | Test.java:103:47:103:51 | thing |
| Test.java:103:34:103:40 | A(...) | Test.java:103:47:103:51 | thing |
| Test.java:103:36:103:36 | <anonymous local variable> | Test.java:103:39:103:39 | <anonymous local variable> |
| Test.java:103:39:103:39 | <anonymous local variable> | Test.java:103:34:103:40 | A(...) |
| Test.java:103:47:103:51 | thing | Test.java:103:47:103:62 | toString(...) |
| Test.java:103:47:103:62 | toString(...) | Test.java:103:71:103:75 | "abc" |
| Test.java:103:47:103:76 | equals(...) | Test.java:104:8:104:20 | case <Pattern> |
| Test.java:103:47:103:76 | equals(...) | Test.java:105:10:105:15 | break |
| Test.java:103:71:103:75 | "abc" | Test.java:103:47:103:76 | equals(...) |
| Test.java:104:8:104:20 | case <Pattern> | Test.java:104:19:104:19 | <anonymous local variable> |
| Test.java:104:8:104:20 | case <Pattern> | Test.java:106:8:106:15 | default |
| Test.java:104:19:104:19 | <anonymous local variable> | Test.java:105:10:105:15 | break |
| Test.java:105:10:105:15 | break | Test.java:110:6:117:7 | var ...; |
| Test.java:106:8:106:15 | default | Test.java:107:10:107:15 | break |
| Test.java:107:10:107:15 | break | Test.java:110:6:117:7 | var ...; |
| Test.java:110:6:117:7 | var ...; | Test.java:110:19:110:31 | switch (...) |
| Test.java:110:10:110:31 | result | Test.java:119:6:119:27 | switch (...) |
| Test.java:110:19:110:31 | switch (...) | Test.java:110:26:110:30 | thing |
| Test.java:110:26:110:30 | thing | Test.java:111:8:111:20 | case <Pattern> |
| Test.java:111:8:111:20 | case <Pattern> | Test.java:111:15:111:15 | <anonymous local variable> |
| Test.java:111:8:111:20 | case <Pattern> | Test.java:112:8:112:77 | case <Pattern> |
| Test.java:111:13:111:19 | B(...) | Test.java:114:10:114:17 | yield ... |
| Test.java:111:15:111:15 | <anonymous local variable> | Test.java:111:18:111:18 | <anonymous local variable> |
| Test.java:111:18:111:18 | <anonymous local variable> | Test.java:111:13:111:19 | B(...) |
| Test.java:112:8:112:77 | case <Pattern> | Test.java:112:21:112:21 | <anonymous local variable> |
| Test.java:112:8:112:77 | case <Pattern> | Test.java:112:31:112:31 | <anonymous local variable> |
| Test.java:112:8:112:77 | case <Pattern> | Test.java:112:36:112:36 | <anonymous local variable> |
| Test.java:112:8:112:77 | case <Pattern> | Test.java:113:8:113:20 | case <Pattern> |
| Test.java:112:21:112:21 | <anonymous local variable> | Test.java:112:47:112:51 | thing |
| Test.java:112:31:112:31 | <anonymous local variable> | Test.java:112:47:112:51 | thing |
| Test.java:112:34:112:40 | A(...) | Test.java:112:47:112:51 | thing |
| Test.java:112:36:112:36 | <anonymous local variable> | Test.java:112:39:112:39 | <anonymous local variable> |
| Test.java:112:39:112:39 | <anonymous local variable> | Test.java:112:34:112:40 | A(...) |
| Test.java:112:47:112:51 | thing | Test.java:112:47:112:62 | toString(...) |
| Test.java:112:47:112:62 | toString(...) | Test.java:112:71:112:75 | "abc" |
| Test.java:112:47:112:76 | equals(...) | Test.java:113:8:113:20 | case <Pattern> |
| Test.java:112:47:112:76 | equals(...) | Test.java:114:10:114:17 | yield ... |
| Test.java:112:71:112:75 | "abc" | Test.java:112:47:112:76 | equals(...) |
| Test.java:113:8:113:20 | case <Pattern> | Test.java:113:19:113:19 | <anonymous local variable> |
| Test.java:113:8:113:20 | case <Pattern> | Test.java:115:8:115:15 | default |
| Test.java:113:19:113:19 | <anonymous local variable> | Test.java:114:10:114:17 | yield ... |
| Test.java:114:10:114:17 | yield ... | Test.java:114:16:114:16 | 1 |
| Test.java:114:16:114:16 | 1 | Test.java:110:10:110:31 | result |
| Test.java:115:8:115:15 | default | Test.java:116:10:116:17 | yield ... |
| Test.java:116:10:116:17 | yield ... | Test.java:116:16:116:16 | 2 |
| Test.java:116:16:116:16 | 2 | Test.java:110:10:110:31 | result |
| Test.java:119:6:119:27 | switch (...) | Test.java:119:22:119:26 | thing |
| Test.java:119:14:119:26 | (...)... | Test.java:120:8:120:16 | case ... |
| Test.java:119:14:119:26 | (...)... | Test.java:121:8:121:56 | case <Pattern> |
| Test.java:119:22:119:26 | thing | Test.java:119:14:119:26 | (...)... |
| Test.java:120:8:120:16 | case ... | Test.java:122:8:122:16 | case ... |
| Test.java:121:8:121:56 | case <Pattern> | Test.java:121:20:121:20 | <anonymous local variable> |
| Test.java:121:8:121:56 | case <Pattern> | Test.java:122:8:122:16 | case ... |
| Test.java:121:8:121:56 | case <Pattern> | Test.java:124:8:124:15 | default |
| Test.java:121:20:121:20 | <anonymous local variable> | Test.java:121:36:121:40 | thing |
| Test.java:121:27:121:50 | length(...) | Test.java:121:55:121:55 | 5 |
| Test.java:121:27:121:55 | ... == ... | Test.java:122:8:122:16 | case ... |
| Test.java:121:27:121:55 | ... == ... | Test.java:124:8:124:15 | default |
| Test.java:121:28:121:40 | (...)... | Test.java:121:27:121:50 | length(...) |
| Test.java:121:36:121:40 | thing | Test.java:121:28:121:40 | (...)... |
| Test.java:121:55:121:55 | 5 | Test.java:121:27:121:55 | ... == ... |
| Test.java:122:8:122:16 | case ... | Test.java:123:10:123:15 | break |
| Test.java:123:10:123:15 | break | Test.java:129:6:129:18 | switch (...) |
| Test.java:124:8:124:15 | default | Test.java:125:10:125:15 | break |
| Test.java:125:10:125:15 | break | Test.java:129:6:129:18 | switch (...) |
| Test.java:129:6:129:18 | switch (...) | Test.java:129:13:129:17 | thing |
| Test.java:129:13:129:17 | thing | Test.java:130:8:130:21 | case <Pattern> |
| Test.java:130:8:130:21 | case <Pattern> | Test.java:130:20:130:20 | <anonymous local variable> |
| Test.java:130:8:130:21 | case <Pattern> | Test.java:131:8:131:15 | default |
| Test.java:130:20:130:20 | <anonymous local variable> | Test.java:131:8:131:15 | default |
| Test.java:131:8:131:15 | default | Test.java:3:22:3:25 | test |
| Test.java:138:8:138:8 | ...=... | Test.java:138:8:138:8 | <Expr>; |
| Test.java:138:8:138:8 | ...=... | Test.java:138:8:138:8 | A |
| Test.java:138:8:138:8 | <Expr>; | Test.java:138:8:138:8 | this |
| Test.java:138:8:138:8 | <Expr>; | Test.java:138:8:138:8 | this |
| Test.java:138:8:138:8 | b | Test.java:138:8:138:8 | ...=... |
| Test.java:138:8:138:8 | field3 | Test.java:138:8:138:8 | ...=... |
| Test.java:138:8:138:8 | super(...) | Test.java:138:8:138:8 | <Expr>; |
| Test.java:138:8:138:8 | this | Test.java:138:8:138:8 | b |
| Test.java:138:8:138:8 | this | Test.java:138:8:138:8 | field3 |
| Test.java:138:8:138:8 | { ... } | Test.java:138:8:138:8 | super(...) |
| Test.java:139:8:139:8 | ...=... | Test.java:139:8:139:8 | <Expr>; |
| Test.java:139:8:139:8 | ...=... | Test.java:139:8:139:8 | B |
| Test.java:139:8:139:8 | <Expr>; | Test.java:139:8:139:8 | this |
| Test.java:139:8:139:8 | <Expr>; | Test.java:139:8:139:8 | this |
| Test.java:139:8:139:8 | field1 | Test.java:139:8:139:8 | ...=... |
| Test.java:139:8:139:8 | field2 | Test.java:139:8:139:8 | ...=... |
| Test.java:139:8:139:8 | super(...) | Test.java:139:8:139:8 | <Expr>; |
| Test.java:139:8:139:8 | this | Test.java:139:8:139:8 | field1 |
| Test.java:139:8:139:8 | this | Test.java:139:8:139:8 | field2 |
| Test.java:139:8:139:8 | { ... } | Test.java:139:8:139:8 | super(...) |

View File

@@ -45,6 +45,13 @@ public class Test {
if (o instanceof R(S(var x), var y)) { }
switch(o) {
case String _, Integer _:
case R(S(_), _):
default:
break;
}
}
}

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args --release 21
//semmle-extractor-options: --javac-args --release 22

View File

@@ -84,5 +84,11 @@
| Test.java:1:14:1:17 | Test | 83 | } |
| Test.java:1:14:1:17 | Test | 84 | if (o instanceof R(S(var x), var y)) { |
| Test.java:1:14:1:17 | Test | 85 | } |
| Test.java:1:14:1:17 | Test | 86 | } |
| Test.java:1:14:1:17 | Test | 87 | } |
| Test.java:1:14:1:17 | Test | 86 | switch (o) { |
| Test.java:1:14:1:17 | Test | 87 | case String _, Integer _: |
| Test.java:1:14:1:17 | Test | 88 | case R(S(var _), var _): |
| Test.java:1:14:1:17 | Test | 89 | default: |
| Test.java:1:14:1:17 | Test | 90 | break; |
| Test.java:1:14:1:17 | Test | 91 | } |
| Test.java:1:14:1:17 | Test | 92 | } |
| Test.java:1:14:1:17 | Test | 93 | } |

View File

@@ -0,0 +1,181 @@
import java.io.Closeable;
import java.util.List;
import java.util.function.BiFunction;
record SubRecord(int z) { }
record MyRecord(int x, SubRecord y) { }
public class AnonDecls {
public static void test(List<String> ss, Object o) {
// Note each construct is repeated to ensure this doesn't produce database inconsistencies
int _ = 1;
int _ = 2;
try (Closeable _ = null) { } catch (Exception _) { }
try (Closeable _ = null) { } catch (Exception _) { }
int x = 0;
for (int _ = 1; x < 10; x++) { }
for (int _ = 2; x > 0; x--) { }
for (var _ : ss) { }
for (var _ : ss) { }
BiFunction<Integer, Integer, Integer> f1 = (_, _) -> 1;
BiFunction<Integer, Integer, Integer> f2 = (_, _) -> 2;
switch (o) {
case SubRecord _:
case MyRecord _:
default:
}
switch (o) {
case SubRecord _:
case MyRecord (int _, SubRecord _):
default:
}
switch (o) {
case SubRecord _:
case MyRecord (int _, SubRecord (int _)):
default:
}
switch (o) {
case SubRecord _:
case MyRecord (_, _):
default:
}
switch (o) {
case MyRecord (_, _), SubRecord(_):
default:
}
switch (o) {
case MyRecord (_, _), SubRecord(_) when ss != null:
default:
}
switch (o) {
// Note use of binding patterns, not records with unnamed patterns as above
case MyRecord _, SubRecord _:
default:
}
switch (o) {
case SubRecord _ -> { }
case MyRecord _ -> { }
default -> { }
}
switch (o) {
case SubRecord _ -> { }
case MyRecord (int _, SubRecord _) -> { }
default -> { }
}
switch (o) {
case SubRecord _ -> { }
case MyRecord (int _, SubRecord (int _)) -> { }
default -> { }
}
switch (o) {
case SubRecord _ -> { }
case MyRecord (_, _) -> { }
default -> { }
}
switch (o) {
case MyRecord (_, _), SubRecord(_) -> { }
default -> { }
}
switch (o) {
case MyRecord (_, _), SubRecord(_) when ss != null -> { }
default -> { }
}
var x1 = switch (o) {
case SubRecord _:
case MyRecord _:
default:
yield 1;
};
var x2 = switch (o) {
case SubRecord _:
case MyRecord (int _, SubRecord _):
default:
yield 1;
};
var x3 = switch (o) {
case SubRecord _:
case MyRecord (int _, SubRecord (int _)):
default:
yield 1;
};
var x4 = switch (o) {
case SubRecord _:
case MyRecord (_, _):
default:
yield 1;
};
var x5 = switch (o) {
case MyRecord (_, _), SubRecord(_):
default:
yield 1;
};
var x6 = switch (o) {
case MyRecord (_, _), SubRecord(_) when ss != null:
default:
yield 1;
};
var x7 = switch (o) {
case SubRecord _ -> 1;
case MyRecord _ -> 2;
default -> 3;
};
var x8 = switch (o) {
case SubRecord _ -> 1;
case MyRecord (int _, SubRecord _) -> 2;
default -> 3;
};
var x9 = switch (o) {
case SubRecord _ -> 1;
case MyRecord (int _, SubRecord (int _)) -> 2;
default -> 3;
};
var x10 = switch (o) {
case SubRecord _ -> 1;
case MyRecord (_, _) -> 2;
default -> 3;
};
var x11 = switch (o) {
case MyRecord (_, _), SubRecord(_) -> 1;
default -> 2;
};
var x12 = switch (o) {
case MyRecord (_, _), SubRecord(_) when ss != null -> 1;
default -> 2;
};
}
}

View File

@@ -127,7 +127,7 @@ A.java:
# 54| -1: [VarAccess] System.out
# 54| -1: [TypeAccess] System
# 54| 0: [VarAccess] s
#-----| 0: (Single Local Variable Declaration)
#-----| 0: (Pattern case declaration)
# 54| 0: [TypeAccess] String
# 54| 1: [LocalVariableDeclExpr] s
# 55| 1: [PatternCase] case <Pattern>
@@ -138,7 +138,7 @@ A.java:
# 55| 0: [AddExpr] ... + ...
# 55| 0: [StringLiteral] "An integer: "
# 55| 1: [VarAccess] i
#-----| 0: (Single Local Variable Declaration)
#-----| 0: (Pattern case declaration)
# 55| 0: [TypeAccess] Integer
# 55| 1: [LocalVariableDeclExpr] i
# 56| 2: [DefaultCase] default
@@ -146,7 +146,7 @@ A.java:
# 58| 3: [SwitchStmt] switch (...)
# 58| -1: [VarAccess] thing
# 59| 0: [PatternCase] case <Pattern>
#-----| 0: (Single Local Variable Declaration)
#-----| 0: (Pattern case declaration)
# 59| 0: [TypeAccess] String
# 59| 1: [LocalVariableDeclExpr] s
# 60| 1: [ExprStmt] <Expr>;
@@ -156,7 +156,7 @@ A.java:
# 60| 0: [VarAccess] s
# 61| 2: [BreakStmt] break
# 62| 3: [PatternCase] case <Pattern>
#-----| 0: (Single Local Variable Declaration)
#-----| 0: (Pattern case declaration)
# 62| 0: [TypeAccess] Integer
# 62| 1: [LocalVariableDeclExpr] i
# 63| 4: [ExprStmt] <Expr>;
@@ -175,14 +175,14 @@ A.java:
# 68| -1: [VarAccess] thing
# 69| 0: [PatternCase] case <Pattern>
# 69| -1: [VarAccess] s
#-----| 0: (Single Local Variable Declaration)
#-----| 0: (Pattern case declaration)
# 69| 0: [TypeAccess] String
# 69| 1: [LocalVariableDeclExpr] s
# 70| 1: [PatternCase] case <Pattern>
# 70| -1: [AddExpr] ... + ...
# 70| 0: [StringLiteral] "An integer: "
# 70| 1: [VarAccess] i
#-----| 0: (Single Local Variable Declaration)
#-----| 0: (Pattern case declaration)
# 70| 0: [TypeAccess] Integer
# 70| 1: [LocalVariableDeclExpr] i
# 71| 2: [DefaultCase] default
@@ -192,13 +192,13 @@ A.java:
# 73| 0: [SwitchExpr] switch (...)
# 73| -1: [VarAccess] thing
# 74| 0: [PatternCase] case <Pattern>
#-----| 0: (Single Local Variable Declaration)
#-----| 0: (Pattern case declaration)
# 74| 0: [TypeAccess] String
# 74| 1: [LocalVariableDeclExpr] s
# 75| 1: [YieldStmt] yield ...
# 75| 0: [VarAccess] s
# 76| 2: [PatternCase] case <Pattern>
#-----| 0: (Single Local Variable Declaration)
#-----| 0: (Pattern case declaration)
# 76| 0: [TypeAccess] Integer
# 76| 1: [LocalVariableDeclExpr] i
# 77| 3: [YieldStmt] yield ...
@@ -232,7 +232,7 @@ A.java:
# 87| -1: [VarAccess] s
# 87| 1: [IntegerLiteral] 3
# 87| -1: [StringLiteral] "It's 3 letters long"
#-----| 0: (Single Local Variable Declaration)
#-----| 0: (Pattern case declaration)
# 87| 0: [TypeAccess] String
# 87| 1: [LocalVariableDeclExpr] s
# 88| 2: [PatternCase] case <Pattern>
@@ -241,7 +241,7 @@ A.java:
# 88| -1: [VarAccess] s
# 88| 1: [IntegerLiteral] 5
# 88| -1: [StringLiteral] "it's 5 letters long"
#-----| 0: (Single Local Variable Declaration)
#-----| 0: (Pattern case declaration)
# 88| 0: [TypeAccess] String
# 88| 1: [LocalVariableDeclExpr] s
# 89| 3: [DefaultCase] default
@@ -252,7 +252,7 @@ A.java:
# 91| -1: [VarAccess] thing
# 92| 0: [PatternCase] case <Pattern>
# 92| -1: [StringLiteral] "It's a string"
#-----| 0: (Single Local Variable Declaration)
#-----| 0: (Pattern case declaration)
# 92| 0: [TypeAccess] String
# 92| 1: [LocalVariableDeclExpr] s
# 93| 1: [NullDefaultCase] case null, default
@@ -332,3 +332,486 @@ A.java:
# 130| 2: [FieldDeclaration] String field;
# 131| 3: [Class] Middle
# 131| 2: [FieldDeclaration] Inner inner;
AnonDecls.java:
# 0| [CompilationUnit] AnonDecls
#-----| -1: (Imports)
# 1| 1: [ImportType] import Closeable
# 2| 2: [ImportType] import List
# 3| 3: [ImportType] import BiFunction
# 5| 1: [Class] SubRecord
# 5| 2: [FieldDeclaration] int z;
# 6| 2: [Class] MyRecord
# 6| 2: [FieldDeclaration] int x;
# 6| 3: [FieldDeclaration] SubRecord y;
# 8| 3: [Class] AnonDecls
# 10| 2: [Method] test
# 10| 3: [TypeAccess] void
#-----| 4: (Parameters)
# 10| 0: [Parameter] ss
# 10| 0: [TypeAccess] List<String>
# 10| 0: [TypeAccess] String
# 10| 1: [Parameter] o
# 10| 0: [TypeAccess] Object
# 10| 5: [BlockStmt] { ... }
# 14| 0: [LocalVariableDeclStmt] var ...;
# 14| 0: [TypeAccess] int
# 14| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 14| 0: [IntegerLiteral] 1
# 15| 1: [LocalVariableDeclStmt] var ...;
# 15| 0: [TypeAccess] int
# 15| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 15| 0: [IntegerLiteral] 2
# 17| 2: [TryStmt] try ...
# 17| -3: [LocalVariableDeclStmt] var ...;
# 17| 0: [TypeAccess] Closeable
# 17| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 17| 0: [NullLiteral] null
# 17| -1: [BlockStmt] { ... }
# 17| 0: [CatchClause] catch (...)
#-----| 0: (Single Local Variable Declaration)
# 17| 0: [TypeAccess] Exception
# 17| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 17| 1: [BlockStmt] { ... }
# 18| 3: [TryStmt] try ...
# 18| -3: [LocalVariableDeclStmt] var ...;
# 18| 0: [TypeAccess] Closeable
# 18| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 18| 0: [NullLiteral] null
# 18| -1: [BlockStmt] { ... }
# 18| 0: [CatchClause] catch (...)
#-----| 0: (Single Local Variable Declaration)
# 18| 0: [TypeAccess] Exception
# 18| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 18| 1: [BlockStmt] { ... }
# 20| 4: [LocalVariableDeclStmt] var ...;
# 20| 0: [TypeAccess] int
# 20| 1: [LocalVariableDeclExpr] x
# 20| 0: [IntegerLiteral] 0
# 22| 5: [ForStmt] for (...;...;...)
#-----| 0: (For Initializers)
# 22| 0: [TypeAccess] int
# 22| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 22| 0: [IntegerLiteral] 1
# 22| 1: [LTExpr] ... < ...
# 22| 0: [VarAccess] x
# 22| 1: [IntegerLiteral] 10
# 22| 2: [BlockStmt] { ... }
# 22| 3: [PostIncExpr] ...++
# 22| 0: [VarAccess] x
# 23| 6: [ForStmt] for (...;...;...)
#-----| 0: (For Initializers)
# 23| 0: [TypeAccess] int
# 23| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 23| 0: [IntegerLiteral] 2
# 23| 1: [GTExpr] ... > ...
# 23| 0: [VarAccess] x
# 23| 1: [IntegerLiteral] 0
# 23| 2: [BlockStmt] { ... }
# 23| 3: [PostDecExpr] ...--
# 23| 0: [VarAccess] x
# 25| 7: [EnhancedForStmt] for (... : ...)
#-----| 0: (Single Local Variable Declaration)
# 25| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 25| 1: [VarAccess] ss
# 25| 2: [BlockStmt] { ... }
# 26| 8: [EnhancedForStmt] for (... : ...)
#-----| 0: (Single Local Variable Declaration)
# 26| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 26| 1: [VarAccess] ss
# 26| 2: [BlockStmt] { ... }
# 28| 9: [LocalVariableDeclStmt] var ...;
# 28| 0: [TypeAccess] BiFunction<Integer,Integer,Integer>
# 28| 0: [TypeAccess] Integer
# 28| 1: [TypeAccess] Integer
# 28| 2: [TypeAccess] Integer
# 28| 1: [LocalVariableDeclExpr] f1
# 28| 0: [LambdaExpr] ...->...
# 28| -4: [AnonymousClass] new BiFunction<Integer,Integer,Integer>(...) { ... }
# 28| 2: [Method] apply
#-----| 4: (Parameters)
# 28| 0: [Parameter] <anonymous parameter>
# 28| 1: [Parameter] <anonymous parameter>
# 28| 5: [BlockStmt] { ... }
# 28| 0: [ReturnStmt] return ...
# 28| 0: [IntegerLiteral] 1
# 28| -3: [TypeAccess] BiFunction<Integer,Integer,Integer>
# 28| 0: [TypeAccess] Integer
# 28| 1: [TypeAccess] Integer
# 28| 2: [TypeAccess] Integer
# 29| 10: [LocalVariableDeclStmt] var ...;
# 29| 0: [TypeAccess] BiFunction<Integer,Integer,Integer>
# 29| 0: [TypeAccess] Integer
# 29| 1: [TypeAccess] Integer
# 29| 2: [TypeAccess] Integer
# 29| 1: [LocalVariableDeclExpr] f2
# 29| 0: [LambdaExpr] ...->...
# 29| -4: [AnonymousClass] new BiFunction<Integer,Integer,Integer>(...) { ... }
# 29| 2: [Method] apply
#-----| 4: (Parameters)
# 29| 0: [Parameter] <anonymous parameter>
# 29| 1: [Parameter] <anonymous parameter>
# 29| 5: [BlockStmt] { ... }
# 29| 0: [ReturnStmt] return ...
# 29| 0: [IntegerLiteral] 2
# 29| -3: [TypeAccess] BiFunction<Integer,Integer,Integer>
# 29| 0: [TypeAccess] Integer
# 29| 1: [TypeAccess] Integer
# 29| 2: [TypeAccess] Integer
# 31| 11: [SwitchStmt] switch (...)
# 31| -1: [VarAccess] o
# 32| 0: [PatternCase] case <Pattern>
#-----| 0: (Pattern case declaration)
# 32| 0: [TypeAccess] SubRecord
# 32| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 33| 1: [PatternCase] case <Pattern>
#-----| 0: (Pattern case declaration)
# 33| 0: [TypeAccess] MyRecord
# 33| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 34| 2: [DefaultCase] default
# 37| 12: [SwitchStmt] switch (...)
# 37| -1: [VarAccess] o
# 38| 0: [PatternCase] case <Pattern>
#-----| 0: (Pattern case declaration)
# 38| 0: [TypeAccess] SubRecord
# 38| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 39| 1: [PatternCase] case <Pattern>
# 39| 0: [RecordPatternExpr] MyRecord(...)
# 39| -2: [TypeAccess] SubRecord
# 39| -1: [TypeAccess] int
# 39| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 39| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 40| 2: [DefaultCase] default
# 43| 13: [SwitchStmt] switch (...)
# 43| -1: [VarAccess] o
# 44| 0: [PatternCase] case <Pattern>
#-----| 0: (Pattern case declaration)
# 44| 0: [TypeAccess] SubRecord
# 44| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 45| 1: [PatternCase] case <Pattern>
# 45| 0: [RecordPatternExpr] MyRecord(...)
# 45| -1: [TypeAccess] int
# 45| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 45| 1: [RecordPatternExpr] SubRecord(...)
# 45| -1: [TypeAccess] int
# 45| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 46| 2: [DefaultCase] default
# 49| 14: [SwitchStmt] switch (...)
# 49| -1: [VarAccess] o
# 50| 0: [PatternCase] case <Pattern>
#-----| 0: (Pattern case declaration)
# 50| 0: [TypeAccess] SubRecord
# 50| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 51| 1: [PatternCase] case <Pattern>
# 51| 0: [RecordPatternExpr] MyRecord(...)
# 51| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 51| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 52| 2: [DefaultCase] default
# 55| 15: [SwitchStmt] switch (...)
# 55| -1: [VarAccess] o
# 56| 0: [PatternCase] case <Pattern>
# 56| 0: [RecordPatternExpr] MyRecord(...)
# 56| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 56| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 56| 1: [RecordPatternExpr] SubRecord(...)
# 56| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 57| 1: [DefaultCase] default
# 60| 16: [SwitchStmt] switch (...)
# 60| -1: [VarAccess] o
# 61| 0: [PatternCase] case <Pattern>
# 61| -3: [NEExpr] ... != ...
# 61| 0: [VarAccess] ss
# 61| 1: [NullLiteral] null
# 61| 0: [RecordPatternExpr] MyRecord(...)
# 61| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 61| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 61| 1: [RecordPatternExpr] SubRecord(...)
# 61| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 62| 1: [DefaultCase] default
# 65| 17: [SwitchStmt] switch (...)
# 65| -1: [VarAccess] o
# 67| 0: [PatternCase] case <Pattern>
#-----| 0: (Pattern case declaration)
# 67| 0: [TypeAccess] MyRecord
# 67| 1: [LocalVariableDeclExpr] <anonymous local variable>
#-----| 1: (Pattern case declaration)
# 67| 0: [TypeAccess] SubRecord
# 67| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 68| 1: [DefaultCase] default
# 71| 18: [SwitchStmt] switch (...)
# 71| -1: [VarAccess] o
# 72| 0: [PatternCase] case <Pattern>
# 72| -1: [BlockStmt] { ... }
#-----| 0: (Pattern case declaration)
# 72| 0: [TypeAccess] SubRecord
# 72| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 73| 1: [PatternCase] case <Pattern>
# 73| -1: [BlockStmt] { ... }
#-----| 0: (Pattern case declaration)
# 73| 0: [TypeAccess] MyRecord
# 73| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 74| 2: [DefaultCase] default
# 74| -1: [BlockStmt] { ... }
# 77| 19: [SwitchStmt] switch (...)
# 77| -1: [VarAccess] o
# 78| 0: [PatternCase] case <Pattern>
# 78| -1: [BlockStmt] { ... }
#-----| 0: (Pattern case declaration)
# 78| 0: [TypeAccess] SubRecord
# 78| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 79| 1: [PatternCase] case <Pattern>
# 79| -1: [BlockStmt] { ... }
# 79| 0: [RecordPatternExpr] MyRecord(...)
# 79| -2: [TypeAccess] SubRecord
# 79| -1: [TypeAccess] int
# 79| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 79| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 80| 2: [DefaultCase] default
# 80| -1: [BlockStmt] { ... }
# 83| 20: [SwitchStmt] switch (...)
# 83| -1: [VarAccess] o
# 84| 0: [PatternCase] case <Pattern>
# 84| -1: [BlockStmt] { ... }
#-----| 0: (Pattern case declaration)
# 84| 0: [TypeAccess] SubRecord
# 84| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 85| 1: [PatternCase] case <Pattern>
# 85| -1: [BlockStmt] { ... }
# 85| 0: [RecordPatternExpr] MyRecord(...)
# 85| -1: [TypeAccess] int
# 85| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 85| 1: [RecordPatternExpr] SubRecord(...)
# 85| -1: [TypeAccess] int
# 85| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 86| 2: [DefaultCase] default
# 86| -1: [BlockStmt] { ... }
# 89| 21: [SwitchStmt] switch (...)
# 89| -1: [VarAccess] o
# 90| 0: [PatternCase] case <Pattern>
# 90| -1: [BlockStmt] { ... }
#-----| 0: (Pattern case declaration)
# 90| 0: [TypeAccess] SubRecord
# 90| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 91| 1: [PatternCase] case <Pattern>
# 91| -1: [BlockStmt] { ... }
# 91| 0: [RecordPatternExpr] MyRecord(...)
# 91| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 91| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 92| 2: [DefaultCase] default
# 92| -1: [BlockStmt] { ... }
# 95| 22: [SwitchStmt] switch (...)
# 95| -1: [VarAccess] o
# 96| 0: [PatternCase] case <Pattern>
# 96| -1: [BlockStmt] { ... }
# 96| 0: [RecordPatternExpr] MyRecord(...)
# 96| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 96| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 96| 1: [RecordPatternExpr] SubRecord(...)
# 96| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 97| 1: [DefaultCase] default
# 97| -1: [BlockStmt] { ... }
# 100| 23: [SwitchStmt] switch (...)
# 100| -1: [VarAccess] o
# 101| 0: [PatternCase] case <Pattern>
# 101| -3: [NEExpr] ... != ...
# 101| 0: [VarAccess] ss
# 101| 1: [NullLiteral] null
# 101| -1: [BlockStmt] { ... }
# 101| 0: [RecordPatternExpr] MyRecord(...)
# 101| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 101| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 101| 1: [RecordPatternExpr] SubRecord(...)
# 101| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 102| 1: [DefaultCase] default
# 102| -1: [BlockStmt] { ... }
# 105| 24: [LocalVariableDeclStmt] var ...;
# 105| 1: [LocalVariableDeclExpr] x1
# 105| 0: [SwitchExpr] switch (...)
# 105| -1: [VarAccess] o
# 106| 0: [PatternCase] case <Pattern>
#-----| 0: (Pattern case declaration)
# 106| 0: [TypeAccess] SubRecord
# 106| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 107| 1: [PatternCase] case <Pattern>
#-----| 0: (Pattern case declaration)
# 107| 0: [TypeAccess] MyRecord
# 107| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 108| 2: [DefaultCase] default
# 109| 3: [YieldStmt] yield ...
# 109| 0: [IntegerLiteral] 1
# 112| 25: [LocalVariableDeclStmt] var ...;
# 112| 1: [LocalVariableDeclExpr] x2
# 112| 0: [SwitchExpr] switch (...)
# 112| -1: [VarAccess] o
# 113| 0: [PatternCase] case <Pattern>
#-----| 0: (Pattern case declaration)
# 113| 0: [TypeAccess] SubRecord
# 113| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 114| 1: [PatternCase] case <Pattern>
# 114| 0: [RecordPatternExpr] MyRecord(...)
# 114| -2: [TypeAccess] SubRecord
# 114| -1: [TypeAccess] int
# 114| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 114| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 115| 2: [DefaultCase] default
# 116| 3: [YieldStmt] yield ...
# 116| 0: [IntegerLiteral] 1
# 119| 26: [LocalVariableDeclStmt] var ...;
# 119| 1: [LocalVariableDeclExpr] x3
# 119| 0: [SwitchExpr] switch (...)
# 119| -1: [VarAccess] o
# 120| 0: [PatternCase] case <Pattern>
#-----| 0: (Pattern case declaration)
# 120| 0: [TypeAccess] SubRecord
# 120| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 121| 1: [PatternCase] case <Pattern>
# 121| 0: [RecordPatternExpr] MyRecord(...)
# 121| -1: [TypeAccess] int
# 121| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 121| 1: [RecordPatternExpr] SubRecord(...)
# 121| -1: [TypeAccess] int
# 121| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 122| 2: [DefaultCase] default
# 123| 3: [YieldStmt] yield ...
# 123| 0: [IntegerLiteral] 1
# 126| 27: [LocalVariableDeclStmt] var ...;
# 126| 1: [LocalVariableDeclExpr] x4
# 126| 0: [SwitchExpr] switch (...)
# 126| -1: [VarAccess] o
# 127| 0: [PatternCase] case <Pattern>
#-----| 0: (Pattern case declaration)
# 127| 0: [TypeAccess] SubRecord
# 127| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 128| 1: [PatternCase] case <Pattern>
# 128| 0: [RecordPatternExpr] MyRecord(...)
# 128| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 128| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 129| 2: [DefaultCase] default
# 130| 3: [YieldStmt] yield ...
# 130| 0: [IntegerLiteral] 1
# 133| 28: [LocalVariableDeclStmt] var ...;
# 133| 1: [LocalVariableDeclExpr] x5
# 133| 0: [SwitchExpr] switch (...)
# 133| -1: [VarAccess] o
# 134| 0: [PatternCase] case <Pattern>
# 134| 0: [RecordPatternExpr] MyRecord(...)
# 134| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 134| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 134| 1: [RecordPatternExpr] SubRecord(...)
# 134| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 135| 1: [DefaultCase] default
# 136| 2: [YieldStmt] yield ...
# 136| 0: [IntegerLiteral] 1
# 139| 29: [LocalVariableDeclStmt] var ...;
# 139| 1: [LocalVariableDeclExpr] x6
# 139| 0: [SwitchExpr] switch (...)
# 139| -1: [VarAccess] o
# 140| 0: [PatternCase] case <Pattern>
# 140| -3: [NEExpr] ... != ...
# 140| 0: [VarAccess] ss
# 140| 1: [NullLiteral] null
# 140| 0: [RecordPatternExpr] MyRecord(...)
# 140| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 140| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 140| 1: [RecordPatternExpr] SubRecord(...)
# 140| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 141| 1: [DefaultCase] default
# 142| 2: [YieldStmt] yield ...
# 142| 0: [IntegerLiteral] 1
# 145| 30: [LocalVariableDeclStmt] var ...;
# 145| 1: [LocalVariableDeclExpr] x7
# 145| 0: [SwitchExpr] switch (...)
# 145| -1: [VarAccess] o
# 146| 0: [PatternCase] case <Pattern>
# 146| -1: [IntegerLiteral] 1
#-----| 0: (Pattern case declaration)
# 146| 0: [TypeAccess] SubRecord
# 146| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 147| 1: [PatternCase] case <Pattern>
# 147| -1: [IntegerLiteral] 2
#-----| 0: (Pattern case declaration)
# 147| 0: [TypeAccess] MyRecord
# 147| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 148| 2: [DefaultCase] default
# 148| -1: [IntegerLiteral] 3
# 151| 31: [LocalVariableDeclStmt] var ...;
# 151| 1: [LocalVariableDeclExpr] x8
# 151| 0: [SwitchExpr] switch (...)
# 151| -1: [VarAccess] o
# 152| 0: [PatternCase] case <Pattern>
# 152| -1: [IntegerLiteral] 1
#-----| 0: (Pattern case declaration)
# 152| 0: [TypeAccess] SubRecord
# 152| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 153| 1: [PatternCase] case <Pattern>
# 153| -1: [IntegerLiteral] 2
# 153| 0: [RecordPatternExpr] MyRecord(...)
# 153| -2: [TypeAccess] SubRecord
# 153| -1: [TypeAccess] int
# 153| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 153| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 154| 2: [DefaultCase] default
# 154| -1: [IntegerLiteral] 3
# 157| 32: [LocalVariableDeclStmt] var ...;
# 157| 1: [LocalVariableDeclExpr] x9
# 157| 0: [SwitchExpr] switch (...)
# 157| -1: [VarAccess] o
# 158| 0: [PatternCase] case <Pattern>
# 158| -1: [IntegerLiteral] 1
#-----| 0: (Pattern case declaration)
# 158| 0: [TypeAccess] SubRecord
# 158| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 159| 1: [PatternCase] case <Pattern>
# 159| -1: [IntegerLiteral] 2
# 159| 0: [RecordPatternExpr] MyRecord(...)
# 159| -1: [TypeAccess] int
# 159| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 159| 1: [RecordPatternExpr] SubRecord(...)
# 159| -1: [TypeAccess] int
# 159| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 160| 2: [DefaultCase] default
# 160| -1: [IntegerLiteral] 3
# 163| 33: [LocalVariableDeclStmt] var ...;
# 163| 1: [LocalVariableDeclExpr] x10
# 163| 0: [SwitchExpr] switch (...)
# 163| -1: [VarAccess] o
# 164| 0: [PatternCase] case <Pattern>
# 164| -1: [IntegerLiteral] 1
#-----| 0: (Pattern case declaration)
# 164| 0: [TypeAccess] SubRecord
# 164| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 165| 1: [PatternCase] case <Pattern>
# 165| -1: [IntegerLiteral] 2
# 165| 0: [RecordPatternExpr] MyRecord(...)
# 165| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 165| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 166| 2: [DefaultCase] default
# 166| -1: [IntegerLiteral] 3
# 169| 34: [LocalVariableDeclStmt] var ...;
# 169| 1: [LocalVariableDeclExpr] x11
# 169| 0: [SwitchExpr] switch (...)
# 169| -1: [VarAccess] o
# 170| 0: [PatternCase] case <Pattern>
# 170| -1: [IntegerLiteral] 1
# 170| 0: [RecordPatternExpr] MyRecord(...)
# 170| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 170| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 170| 1: [RecordPatternExpr] SubRecord(...)
# 170| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 171| 1: [DefaultCase] default
# 171| -1: [IntegerLiteral] 2
# 174| 35: [LocalVariableDeclStmt] var ...;
# 174| 1: [LocalVariableDeclExpr] x12
# 174| 0: [SwitchExpr] switch (...)
# 174| -1: [VarAccess] o
# 175| 0: [PatternCase] case <Pattern>
# 175| -3: [NEExpr] ... != ...
# 175| 0: [VarAccess] ss
# 175| 1: [NullLiteral] null
# 175| -1: [IntegerLiteral] 1
# 175| 0: [RecordPatternExpr] MyRecord(...)
# 175| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 175| 1: [LocalVariableDeclExpr] <anonymous local variable>
# 175| 1: [RecordPatternExpr] SubRecord(...)
# 175| 0: [LocalVariableDeclExpr] <anonymous local variable>
# 176| 1: [DefaultCase] default
# 176| -1: [IntegerLiteral] 2

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args --release 21
//semmle-extractor-options: --javac-args --release 22

View File

@@ -58,6 +58,31 @@ public class Test {
case null: default: i.take(source()); // Can't call C1.take (but we don't currently notice)
}
switch(i) {
case C1 _, C2 _:
i.take(source()); // Must be either C1.take or C2.take (but we don't currently notice, because neither dominates)
break;
default:
i.take(source()); // Can't call C1.take or C2.take (but we don't currently notice, because a multi-pattern case isn't understood as a type test)
}
switch(i) {
case C1 _, C2 _ when i.toString().equals("abc"):
i.take(source()); // Must be either C1.take or C2.take (but we don't currently notice, because neither dominates)
break;
default:
i.take(source()); // Can't call C1.take or C2.take (but we don't currently notice, because a multi-pattern case isn't understood as a type test)
}
switch(i) {
case C1 _:
case C2 _:
i.take(source()); // Must be either C1.take or C2.take (but we don't currently notice, because neither dominates)
break;
default:
i.take(source()); // Can't call C1.take or C2.take
}
}
}

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args --release 21
//semmle-extractor-options: --javac-args --release 22

View File

@@ -30,3 +30,25 @@
| Test.java:58:34:58:41 | source(...) | Test.java:8:65:8:65 | x |
| Test.java:58:34:58:41 | source(...) | Test.java:9:74:9:74 | x |
| Test.java:58:34:58:41 | source(...) | Test.java:10:82:10:82 | x |
| Test.java:63:16:63:23 | source(...) | Test.java:7:65:7:65 | x |
| Test.java:63:16:63:23 | source(...) | Test.java:8:65:8:65 | x |
| Test.java:63:16:63:23 | source(...) | Test.java:9:74:9:74 | x |
| Test.java:63:16:63:23 | source(...) | Test.java:10:82:10:82 | x |
| Test.java:66:16:66:23 | source(...) | Test.java:7:65:7:65 | x |
| Test.java:66:16:66:23 | source(...) | Test.java:8:65:8:65 | x |
| Test.java:66:16:66:23 | source(...) | Test.java:9:74:9:74 | x |
| Test.java:66:16:66:23 | source(...) | Test.java:10:82:10:82 | x |
| Test.java:71:16:71:23 | source(...) | Test.java:7:65:7:65 | x |
| Test.java:71:16:71:23 | source(...) | Test.java:8:65:8:65 | x |
| Test.java:71:16:71:23 | source(...) | Test.java:9:74:9:74 | x |
| Test.java:71:16:71:23 | source(...) | Test.java:10:82:10:82 | x |
| Test.java:74:16:74:23 | source(...) | Test.java:7:65:7:65 | x |
| Test.java:74:16:74:23 | source(...) | Test.java:8:65:8:65 | x |
| Test.java:74:16:74:23 | source(...) | Test.java:9:74:9:74 | x |
| Test.java:74:16:74:23 | source(...) | Test.java:10:82:10:82 | x |
| Test.java:80:16:80:23 | source(...) | Test.java:7:65:7:65 | x |
| Test.java:80:16:80:23 | source(...) | Test.java:8:65:8:65 | x |
| Test.java:80:16:80:23 | source(...) | Test.java:9:74:9:74 | x |
| Test.java:80:16:80:23 | source(...) | Test.java:10:82:10:82 | x |
| Test.java:83:16:83:23 | source(...) | Test.java:9:74:9:74 | x |
| Test.java:83:16:83:23 | source(...) | Test.java:10:82:10:82 | x |

View File

@@ -3,7 +3,7 @@ extensions:
pack: codeql/python-all
extensible: summaryModel
data:
- ["foo", "Member[MS_identity]", "Argument[0]", "ReturnValue", "value"]
- ["foo", "Member[MS_identity]", "Argument[0,x:]", "ReturnValue", "value"]
- ["foo", "Member[MS_apply_lambda]", "Argument[1]", "Argument[0].Parameter[0]", "value"]
- ["foo", "Member[MS_apply_lambda]", "Argument[0].ReturnValue", "ReturnValue", "value"]
- ["foo", "Member[MS_reversed]", "Argument[0].ListElement", "ReturnValue.ListElement", "value"]
@@ -17,4 +17,5 @@ extensions:
- ["foo", "Member[MS_append_to_list]", "Argument[1]", "ReturnValue", "taint"]
- ["foo", "Member[MS_spread]", "Argument[0]", "ReturnValue.TupleElement[0]", "value"]
- ["foo", "Member[MS_spread]", "Argument[1]", "ReturnValue.TupleElement[1]", "value"]
- ["foo", "Member[MS_spread_all]", "Argument[0]", "ReturnValue.TupleElement[0,1]", "value"]
- ["json", "Member[MS_loads]", "Argument[0]", "ReturnValue", "taint"]

View File

@@ -3,7 +3,7 @@ extensions:
pack: codeql/python-all
extensible: summaryModel
data:
- ["foo", "Member[MS_identity]", "Argument[0]", "ReturnValue", "value"]
- ["foo", "Member[MS_identity]", "Argument[0,x:]", "ReturnValue", "value"]
- ["foo", "Member[MS_apply_lambda]", "Argument[1]", "Argument[0].Parameter[0]", "value"]
- ["foo", "Member[MS_apply_lambda]", "Argument[0].ReturnValue", "ReturnValue", "value"]
- ["foo", "Member[MS_reversed]", "Argument[0].ListElement", "ReturnValue.ListElement", "value"]
@@ -17,4 +17,5 @@ extensions:
- ["foo", "Member[MS_append_to_list]", "Argument[1]", "ReturnValue", "taint"]
- ["foo", "Member[MS_spread]", "Argument[0]", "ReturnValue.TupleElement[0]", "value"]
- ["foo", "Member[MS_spread]", "Argument[1]", "ReturnValue.TupleElement[1]", "value"]
- ["foo", "Member[MS_spread_all]", "Argument[0]", "ReturnValue.TupleElement[0,1]", "value"]
- ["json", "Member[MS_loads]", "Argument[0]", "ReturnValue", "taint"]

View File

@@ -30,12 +30,16 @@ def SINK_F(x):
ensure_tainted = ensure_not_tainted = print
TAINTED_STRING = "TAINTED_STRING"
from foo import MS_identity, MS_apply_lambda, MS_reversed, MS_list_map, MS_append_to_list, MS_spread
from foo import MS_identity, MS_apply_lambda, MS_reversed, MS_list_map, MS_append_to_list, MS_spread, MS_spread_all
# Simple summary
via_identity = MS_identity(SOURCE)
SINK(via_identity) # $ flow="SOURCE, l:-1 -> via_identity"
# Simple summary keyword
via_identity_kw = MS_identity(x = SOURCE)
SINK(via_identity_kw) # $ flow="SOURCE, l:-1 -> via_identity_kw"
# Lambda summary
via_lambda = MS_apply_lambda(lambda x: [x], SOURCE)
SINK(via_lambda[0]) # $ flow="SOURCE, l:-1 -> via_lambda[0]"
@@ -114,6 +118,10 @@ x, y = MS_spread(NONSOURCE, SOURCE)
SINK_F(x)
SINK(y) # $ flow="SOURCE, l:-2 -> y"
a, b = MS_spread_all(SOURCE)
SINK(a) # $ flow="SOURCE, l:-1 -> a"
SINK(b) # $ flow="SOURCE, l:-2 -> b"
# Modeled flow-summary is not value preserving
from json import MS_loads as json_loads

View File

@@ -3749,6 +3749,13 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
private predicate pathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) = fastTC(pathSucc/2)(n1, n2)
private predicate isFlowSource(PathNodeImpl n) { n.isFlowSource() }
private predicate isFlowSink(PathNodeImpl n) { n.isFlowSink() }
private predicate doublyBoundedPathSuccPlus(PathNodeImpl n1, PathNodeImpl n2) =
doublyBoundedFastTC(pathSucc/2, isFlowSource/1, isFlowSink/1)(n1, n2)
/**
* A `Node` augmented with a call context (except for sinks) and an access path.
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
@@ -4437,9 +4444,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
exists(PathNodeImpl flowsource, PathNodeImpl flowsink |
source = flowsource and sink = flowsink
|
flowsource.isFlowSource() and
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
flowsink.isFlowSink()
flowsource.isFlowSource() and flowsink.isFlowSink() and flowsource = flowsink
or
doublyBoundedPathSuccPlus(flowsource, flowsink)
)
}

View File

@@ -1 +1 @@
3.8.14
3.11

View File

@@ -18,7 +18,7 @@ runs:
- name: Run integration tests
shell: bash
run: |
python swift/integration-tests/runner.py --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
python swift/ql/integration-tests/runner.py --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
env:
SEMMLE_DEBUG_TRACER: 10000
- name: Upload test logs
@@ -27,5 +27,5 @@ runs:
with:
name: swift-integration-tests-logs-${{ runner.os }}
path: |
swift/integration-tests/**/db/log
swift/ql/integration-tests/**/db/log
retention-days: 1

View File

@@ -1,5 +0,0 @@
import swift
predicate relevant(Locatable loc) {
loc.getLocation().getFile().getName().matches("%/swift/integration-tests/%/Sources/%")
}

View File

@@ -1,7 +0,0 @@
name: integration-tests-swift
version: 0.0.0
dependencies:
codeql/swift-all: ${workspace}
tests: .
extractor: swift
warnOnImplicitThis: true

View File

@@ -17,5 +17,5 @@ py_test(
"diagnostics.expected",
":assert-false",
],
deps = ["//swift/integration-tests:integration_tests"],
deps = ["//swift/ql/integration-tests:utils"],
)

View File

@@ -2,7 +2,7 @@ import importlib
import os
import subprocess
# We have to use importlib due to the '-' in the path
diagnostics_test_utils = importlib.import_module("swift.integration-tests.diagnostics_test_utils")
diagnostics_test_utils = importlib.import_module("swift.ql.integration-tests.diagnostics_test_utils")
test_dir = "swift/logging/tests/assertion-diagnostics"

View File

@@ -6,5 +6,5 @@ xcuserdata/
DerivedData/
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
*.actual
db
test-db
*.swiftmodule

View File

@@ -1,5 +1,5 @@
py_library(
name = "integration_tests",
name = "utils",
srcs = [
"create_database_utils.py",
"diagnostics_test_utils.py",

View File

@@ -27,8 +27,8 @@ def runUnsuccessfully(cmd):
def run_codeql_database_create(cmds, lang, keep_trap=True, db=None, runFunction=runSuccessfully):
""" db parameter is here solely for compatibility with the internal test runner """
assert lang == 'swift'
codeql_root = pathlib.Path(__file__).parents[2]
shutil.rmtree("db", ignore_errors=True)
codeql_root = pathlib.Path(__file__).parents[3]
shutil.rmtree("test-db", ignore_errors=True)
cmd = [
"codeql", "database", "create",
"-s", ".", "-l", "swift", f"--search-path={codeql_root}", "--no-cleanup",
@@ -37,5 +37,5 @@ def run_codeql_database_create(cmds, lang, keep_trap=True, db=None, runFunction=
cmd.append("--keep-trap")
for c in cmds:
cmd += ["-c", c]
cmd.append("db")
cmd.append("test-db")
runFunction(cmd)

View File

@@ -50,7 +50,7 @@ def _normalize_json(data):
return "\n".join(entries)
def check_diagnostics(test_dir=".", test_db="db", actual = None):
def check_diagnostics(test_dir=".", test_db="test-db", actual = None):
test_dir = pathlib.Path(test_dir)
test_db = pathlib.Path(test_db)
if actual is None:

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