mirror of
https://github.com/github/codeql.git
synced 2026-05-01 19:55:15 +02:00
Merge branch 'main' into js/case-sensitive-middleware
This commit is contained in:
1
.github/workflows/check-change-note.yml
vendored
1
.github/workflows/check-change-note.yml
vendored
@@ -10,6 +10,7 @@ on:
|
||||
- "*/ql/lib/**/*.qll"
|
||||
- "!**/experimental/**"
|
||||
- "!ql/**"
|
||||
- "!swift/**"
|
||||
- ".github/workflows/check-change-note.yml"
|
||||
|
||||
jobs:
|
||||
|
||||
32
.github/workflows/ql-for-ql-build.yml
vendored
32
.github/workflows/ql-for-ql-build.yml
vendored
@@ -19,7 +19,6 @@ jobs:
|
||||
uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980
|
||||
with:
|
||||
languages: javascript # does not matter
|
||||
tools: latest
|
||||
- name: Get CodeQL version
|
||||
id: get-codeql-version
|
||||
run: |
|
||||
@@ -50,9 +49,6 @@ jobs:
|
||||
path: ${{ runner.temp }}/query-pack.zip
|
||||
|
||||
extractors:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -187,7 +183,6 @@ jobs:
|
||||
languages: ql
|
||||
db-location: ${{ runner.temp }}/db
|
||||
config-file: ./ql-for-ql-config.yml
|
||||
tools: latest
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@aa93aea877e5fb8841bcb1193f672abf6e9f2980
|
||||
@@ -195,9 +190,36 @@ jobs:
|
||||
category: "ql-for-ql-${{ matrix.folder }}"
|
||||
- name: Copy sarif file to CWD
|
||||
run: cp ../results/ql.sarif ./${{ matrix.folder }}.sarif
|
||||
- name: Fixup the $scema in sarif # Until https://github.com/microsoft/sarif-vscode-extension/pull/436/ is part in a stable release
|
||||
run: |
|
||||
sed -i 's/\$schema.*/\$schema": "https:\/\/raw.githubusercontent.com\/oasis-tcs\/sarif-spec\/master\/Schemata\/sarif-schema-2.1.0",/' ${{ matrix.folder }}.sarif
|
||||
- name: Sarif as artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.folder }}.sarif
|
||||
path: ${{ matrix.folder }}.sarif
|
||||
|
||||
combine:
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- analyze
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Make a folder for artifacts.
|
||||
run: mkdir -p results
|
||||
- name: Download all sarif files
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
path: results
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: Combine all sarif files
|
||||
run: |
|
||||
node ./ql/scripts/merge-sarif.js results/**/*.sarif combined.sarif
|
||||
- name: Upload combined sarif file
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: combined.sarif
|
||||
path: combined.sarif
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
ql/target
|
||||
key: ${{ runner.os }}-qltest-cargo-${{ hashFiles('ql/**/Cargo.lock') }}
|
||||
- name: Build Extractor
|
||||
run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./create-extractor-pack.sh
|
||||
run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./scripts/create-extractor-pack.sh
|
||||
env:
|
||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
||||
- name: Checkout ${{ matrix.repo }}
|
||||
|
||||
2
.github/workflows/ql-for-ql-tests.yml
vendored
2
.github/workflows/ql-for-ql-tests.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
||||
run: |
|
||||
cd ql;
|
||||
codeqlpath=$(dirname ${{ steps.find-codeql.outputs.codeql-path }});
|
||||
env "PATH=$PATH:$codeqlpath" ./create-extractor-pack.sh
|
||||
env "PATH=$PATH:$codeqlpath" ./scripts/create-extractor-pack.sh
|
||||
- name: Run QL tests
|
||||
run: |
|
||||
"${CODEQL}" test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}/ql/extractor-pack" --consistency-queries ql/ql/consistency-queries ql/ql/test
|
||||
|
||||
34
.github/workflows/swift-integration-tests.yml
vendored
Normal file
34
.github/workflows/swift-integration-tests.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
name: "Swift: Run Integration Tests"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "swift/**"
|
||||
- .github/workflows/swift-integration-tests.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
defaults:
|
||||
run:
|
||||
working-directory: swift
|
||||
|
||||
jobs:
|
||||
integration-tests:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-20.04
|
||||
# - macos-latest TODO
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/fetch-codeql
|
||||
- uses: bazelbuild/setup-bazelisk@v2
|
||||
- uses: actions/setup-python@v3
|
||||
- name: Build Swift extractor
|
||||
run: |
|
||||
bazel run //swift:create-extractor-pack
|
||||
- name: Run integration tests
|
||||
run: |
|
||||
python integration-tests/runner.py
|
||||
@@ -42,3 +42,4 @@ WORKSPACE.bazel @github/codeql-ci-reviewers
|
||||
/.github/workflows/js-ml-tests.yml @github/codeql-ml-powered-queries-reviewers
|
||||
/.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers
|
||||
/.github/workflows/ruby-* @github/codeql-ruby
|
||||
/.github/workflows/swift-* @github/codeql-c
|
||||
|
||||
@@ -453,11 +453,11 @@
|
||||
"python/ql/src/Lexical/CommentedOutCodeReferences.inc.qhelp"
|
||||
],
|
||||
"IDE Contextual Queries": [
|
||||
"cpp/ql/src/IDEContextual.qll",
|
||||
"csharp/ql/src/IDEContextual.qll",
|
||||
"java/ql/src/IDEContextual.qll",
|
||||
"javascript/ql/src/IDEContextual.qll",
|
||||
"python/ql/src/analysis/IDEContextual.qll"
|
||||
"cpp/ql/lib/IDEContextual.qll",
|
||||
"csharp/ql/lib/IDEContextual.qll",
|
||||
"java/ql/lib/IDEContextual.qll",
|
||||
"javascript/ql/lib/IDEContextual.qll",
|
||||
"python/ql/lib/analysis/IDEContextual.qll"
|
||||
],
|
||||
"SSA C#": [
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll",
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
## 0.3.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`.
|
||||
|
||||
## 0.2.3
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* An `isBraced` predicate was added to the `Initializer` class which holds when a C++ braced initializer was used in the initialization.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the the C++ logical and variable declarations in conditions.
|
||||
9
cpp/ql/lib/change-notes/released/0.3.0.md
Normal file
9
cpp/ql/lib/change-notes/released/0.3.0.md
Normal file
@@ -0,0 +1,9 @@
|
||||
## 0.3.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.2.3
|
||||
lastReleaseVersion: 0.3.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.3.0-dev
|
||||
version: 0.3.1-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -46,7 +46,7 @@ predicate nullCheckExpr(Expr checkExpr, Variable var) {
|
||||
or
|
||||
exists(LogicalAndExpr op, AnalysedExpr child |
|
||||
expr = op and
|
||||
op.getRightOperand() = child and
|
||||
op.getAnOperand() = child and
|
||||
nullCheckExpr(child, v)
|
||||
)
|
||||
or
|
||||
@@ -99,7 +99,7 @@ predicate validCheckExpr(Expr checkExpr, Variable var) {
|
||||
or
|
||||
exists(LogicalAndExpr op, AnalysedExpr child |
|
||||
expr = op and
|
||||
op.getRightOperand() = child and
|
||||
op.getAnOperand() = child and
|
||||
validCheckExpr(child, v)
|
||||
)
|
||||
or
|
||||
@@ -169,7 +169,10 @@ class AnalysedExpr extends Expr {
|
||||
*/
|
||||
predicate isDef(LocalScopeVariable v) {
|
||||
this.inCondition() and
|
||||
this.(Assignment).getLValue() = v.getAnAccess()
|
||||
(
|
||||
this.(Assignment).getLValue() = v.getAnAccess() or
|
||||
this.(ConditionDeclExpr).getVariableAccess() = v.getAnAccess()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
|
||||
readSet(node1.asNode(), c, node2.asNode()) and
|
||||
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
@@ -562,7 +562,8 @@ pragma[nomagic]
|
||||
private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
|
||||
contentType) and
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
|
||||
readSet(node1.asNode(), c, node2.asNode()) and
|
||||
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
@@ -562,7 +562,8 @@ pragma[nomagic]
|
||||
private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
|
||||
contentType) and
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
|
||||
readSet(node1.asNode(), c, node2.asNode()) and
|
||||
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
@@ -562,7 +562,8 @@ pragma[nomagic]
|
||||
private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
|
||||
contentType) and
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
|
||||
readSet(node1.asNode(), c, node2.asNode()) and
|
||||
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
@@ -562,7 +562,8 @@ pragma[nomagic]
|
||||
private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
|
||||
contentType) and
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
|
||||
readSet(node1.asNode(), c, node2.asNode()) and
|
||||
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
@@ -562,7 +562,8 @@ pragma[nomagic]
|
||||
private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
|
||||
contentType) and
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
@@ -255,8 +255,10 @@ class FunctionCall extends Call, @funbindexpr {
|
||||
/**
|
||||
* Gets the function called by this call.
|
||||
*
|
||||
* In the case of virtual function calls, the result is the most-specific function in the override tree (as
|
||||
* determined by the compiler) such that the target at runtime will be one of `result.getAnOverridingFunction*()`.
|
||||
* In the case of virtual function calls, the result is the most-specific function in the override tree
|
||||
* such that the target at runtime will be one of `result.getAnOverridingFunction*()`. The most-specific
|
||||
* function is determined by the compiler based on the compile time type of the object the function is a
|
||||
* member of.
|
||||
*/
|
||||
override Function getTarget() { funbind(underlyingElement(this), unresolveElement(result)) }
|
||||
|
||||
|
||||
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
|
||||
readSet(node1.asNode(), c, node2.asNode()) and
|
||||
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
@@ -562,7 +562,8 @@ pragma[nomagic]
|
||||
private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
|
||||
contentType) and
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
|
||||
readSet(node1.asNode(), c, node2.asNode()) and
|
||||
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
@@ -562,7 +562,8 @@ pragma[nomagic]
|
||||
private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
|
||||
contentType) and
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
|
||||
readSet(node1.asNode(), c, node2.asNode()) and
|
||||
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
@@ -562,7 +562,8 @@ pragma[nomagic]
|
||||
private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
|
||||
contentType) and
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
|
||||
readSet(node1.asNode(), c, node2.asNode()) and
|
||||
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
@@ -562,7 +562,8 @@ pragma[nomagic]
|
||||
private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
|
||||
contentType) and
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 0.2.0
|
||||
|
||||
## 0.1.4
|
||||
|
||||
## 0.1.3
|
||||
|
||||
@@ -44,7 +44,7 @@ predicate whiteListWrapped(FunctionCall fc) {
|
||||
|
||||
from FunctionCall c, FloatingPointType t1, IntegralType t2
|
||||
where
|
||||
t1 = c.getTarget().getType().getUnderlyingType() and
|
||||
pragma[only_bind_into](t1) = c.getTarget().getType().getUnderlyingType() and
|
||||
t2 = c.getActualType() and
|
||||
c.hasImplicitConversion() and
|
||||
not whiteListWrapped(c)
|
||||
|
||||
@@ -18,7 +18,7 @@ import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.ir.dataflow.MustFlow
|
||||
import PathGraph
|
||||
|
||||
/** Holds if `f` has a name that we intrepret as evidence of intentionally returning the value of the stack pointer. */
|
||||
/** Holds if `f` has a name that we interpret as evidence of intentionally returning the value of the stack pointer. */
|
||||
predicate intentionallyReturnsStackPointer(Function f) {
|
||||
f.getName().toLowerCase().matches(["%stack%", "%sp%"])
|
||||
}
|
||||
|
||||
@@ -133,7 +133,9 @@ TGlobalAddress globalAddress(Instruction instr) {
|
||||
)
|
||||
or
|
||||
exists(FieldAddressInstruction fai | instr = fai |
|
||||
result = TFieldAddress(globalAddress(fai.getObjectAddress()), fai.getField())
|
||||
result =
|
||||
TFieldAddress(globalAddress(pragma[only_bind_into](fai.getObjectAddress())),
|
||||
pragma[only_bind_out](fai.getField()))
|
||||
)
|
||||
or
|
||||
result = globalAddress(instr.(PointerOffsetInstruction).getLeft())
|
||||
|
||||
@@ -15,6 +15,7 @@ class VariableAccessInInitializer extends VariableAccess {
|
||||
Variable var;
|
||||
Initializer init;
|
||||
|
||||
pragma[nomagic]
|
||||
VariableAccessInInitializer() {
|
||||
init.getDeclaration() = var and
|
||||
init.getExpr().getAChild*() = this
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* Contextual queries and the query libraries they depend on have been moved to the `codeql/cpp-all` package.
|
||||
1
cpp/ql/src/change-notes/released/0.2.0.md
Normal file
1
cpp/ql/src/change-notes/released/0.2.0.md
Normal file
@@ -0,0 +1 @@
|
||||
## 0.2.0
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.1.4
|
||||
lastReleaseVersion: 0.2.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 0.2.0-dev
|
||||
version: 0.2.1-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
| test.cpp:9:9:9:9 | v | test.cpp:5:13:5:13 | v | is not null | is valid |
|
||||
| test.cpp:10:9:10:10 | ! ... | test.cpp:5:13:5:13 | v | is null | is not valid |
|
||||
| test.cpp:11:9:11:14 | ... == ... | test.cpp:5:13:5:13 | v | is null | is not valid |
|
||||
| test.cpp:12:9:12:17 | ... == ... | test.cpp:5:13:5:13 | v | is not null | is valid |
|
||||
| test.cpp:13:9:13:14 | ... != ... | test.cpp:5:13:5:13 | v | is not null | is valid |
|
||||
| test.cpp:14:9:14:17 | ... != ... | test.cpp:5:13:5:13 | v | is null | is not valid |
|
||||
| test.cpp:15:8:15:23 | call to __builtin_expect | test.cpp:5:13:5:13 | v | is not null | is valid |
|
||||
| test.cpp:16:8:16:23 | call to __builtin_expect | test.cpp:5:13:5:13 | v | is null | is not valid |
|
||||
| test.cpp:17:9:17:17 | ... && ... | test.cpp:5:13:5:13 | v | is not null | is valid |
|
||||
| test.cpp:18:9:18:17 | ... && ... | test.cpp:5:13:5:13 | v | is not null | is valid |
|
||||
| test.cpp:19:9:19:18 | ... && ... | test.cpp:5:13:5:13 | v | is null | is not valid |
|
||||
| test.cpp:20:9:20:18 | ... && ... | test.cpp:5:13:5:13 | v | is null | is not valid |
|
||||
| test.cpp:21:9:21:14 | ... = ... | test.cpp:5:13:5:13 | v | is null | is not valid |
|
||||
| test.cpp:21:9:21:14 | ... = ... | test.cpp:7:10:7:10 | b | is not null | is valid |
|
||||
| test.cpp:22:9:22:14 | ... = ... | test.cpp:5:13:5:13 | v | is not null | is not valid |
|
||||
| test.cpp:22:9:22:14 | ... = ... | test.cpp:7:13:7:13 | c | is not null | is not valid |
|
||||
| test.cpp:22:17:22:17 | c | test.cpp:7:13:7:13 | c | is not null | is valid |
|
||||
| test.cpp:23:21:23:21 | x | test.cpp:23:14:23:14 | x | is not null | is valid |
|
||||
| test.cpp:24:9:24:18 | (condition decl) | test.cpp:5:13:5:13 | v | is not null | is not valid |
|
||||
| test.cpp:24:9:24:18 | (condition decl) | test.cpp:24:14:24:14 | y | is not null | is valid |
|
||||
@@ -0,0 +1,8 @@
|
||||
import cpp
|
||||
|
||||
from AnalysedExpr a, LocalScopeVariable v, string isNullCheck, string isValidCheck
|
||||
where
|
||||
v.getAnAccess().getEnclosingStmt() = a.getParent() and
|
||||
(if a.isNullCheck(v) then isNullCheck = "is null" else isNullCheck = "is not null") and
|
||||
(if a.isValidCheck(v) then isValidCheck = "is valid" else isValidCheck = "is not valid")
|
||||
select a, v, isNullCheck, isValidCheck
|
||||
25
cpp/ql/test/library-tests/controlflow/nullness/test.cpp
Normal file
25
cpp/ql/test/library-tests/controlflow/nullness/test.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
// semmle-extractor-options: -std=c++17
|
||||
|
||||
long __builtin_expect(long);
|
||||
|
||||
void f(int *v) {
|
||||
int *w;
|
||||
bool b, c;
|
||||
|
||||
if (v) {}
|
||||
if (!v) {}
|
||||
if (v == 0) {}
|
||||
if ((!v) == 0) {}
|
||||
if (v != 0) {}
|
||||
if ((!v) != 0) {}
|
||||
if(__builtin_expect((long)v)) {}
|
||||
if(__builtin_expect((long)!v)) {}
|
||||
if (true && v) {}
|
||||
if (v && true) {}
|
||||
if (true && !v) {}
|
||||
if (!v && true) {}
|
||||
if (b = !v) {}
|
||||
if (c = !v; c) {}
|
||||
if (int *x = v; x) {}
|
||||
if (int *y = v) {}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
## 1.2.0
|
||||
|
||||
## 1.1.4
|
||||
|
||||
## 1.1.3
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
## 1.2.0
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.1.4
|
||||
lastReleaseVersion: 1.2.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-all
|
||||
version: 1.2.0-dev
|
||||
version: 1.2.1-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 1.2.0
|
||||
|
||||
## 1.1.4
|
||||
|
||||
## 1.1.3
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
## 1.2.0
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.1.4
|
||||
lastReleaseVersion: 1.2.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.2.0-dev
|
||||
version: 1.2.1-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.3.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
|
||||
|
||||
## 0.2.3
|
||||
|
||||
## 0.2.2
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
## 0.3.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.2.3
|
||||
lastReleaseVersion: 0.3.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-all
|
||||
version: 0.3.0-dev
|
||||
version: 0.3.1-dev
|
||||
groups: csharp
|
||||
dbscheme: semmlecode.csharp.dbscheme
|
||||
extractor: csharp
|
||||
|
||||
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
|
||||
readSet(node1.asNode(), c, node2.asNode()) and
|
||||
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
@@ -562,7 +562,8 @@ pragma[nomagic]
|
||||
private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
|
||||
contentType) and
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
|
||||
readSet(node1.asNode(), c, node2.asNode()) and
|
||||
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
@@ -562,7 +562,8 @@ pragma[nomagic]
|
||||
private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
|
||||
contentType) and
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
|
||||
readSet(node1.asNode(), c, node2.asNode()) and
|
||||
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
@@ -562,7 +562,8 @@ pragma[nomagic]
|
||||
private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
|
||||
contentType) and
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
|
||||
readSet(node1.asNode(), c, node2.asNode()) and
|
||||
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
@@ -562,7 +562,8 @@ pragma[nomagic]
|
||||
private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
|
||||
contentType) and
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
|
||||
readSet(node1.asNode(), c, node2.asNode()) and
|
||||
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
@@ -562,7 +562,8 @@ pragma[nomagic]
|
||||
private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
|
||||
contentType) and
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
simpleLocalFlowStepExt(n1, n2) and
|
||||
simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
or
|
||||
@@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config)
|
||||
)
|
||||
@@ -466,7 +466,7 @@ private predicate additionalLocalStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) {
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
jumpStepCached(n1, n2) and
|
||||
jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
)
|
||||
@@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, n2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext
|
||||
@@ -507,7 +507,7 @@ private predicate additionalJumpStateStep(
|
||||
exists(Node n1, Node n2 |
|
||||
node1.asNode() = n1 and
|
||||
node2.asNode() = n2 and
|
||||
config.isAdditionalFlowStep(n1, s1, n2, s2) and
|
||||
config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and
|
||||
getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and
|
||||
stepFilter(node1, node2, config) and
|
||||
not stateBarrier(node1, s1, config) and
|
||||
@@ -518,7 +518,7 @@ private predicate additionalJumpStateStep(
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) {
|
||||
readSet(node1.asNode(), c, node2.asNode()) and
|
||||
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
|
||||
stepFilter(node1, node2, config)
|
||||
or
|
||||
exists(Node n |
|
||||
@@ -562,7 +562,8 @@ pragma[nomagic]
|
||||
private predicate store(
|
||||
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
|
||||
) {
|
||||
store(node1.asNode(), tc, node2.asNode(), contentType) and
|
||||
store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()),
|
||||
contentType) and
|
||||
read(_, tc.getContent(), _, config) and
|
||||
stepFilter(node1, node2, config)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
## 0.2.0
|
||||
|
||||
### Query Metadata Changes
|
||||
|
||||
* The `kind` query metadata was changed to `diagnostic` on `cs/compilation-error`, `cs/compilation-message`, `cs/extraction-error`, and `cs/extraction-message`.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The syntax of the (source|sink|summary)model CSV format has been changed slightly for Java and C#. A new column called `provenance` has been introduced, where the allowed values are `manual` and `generated`. The value used to indicate whether a model as been written by hand (`manual`) or create by the CSV model generator (`generated`).
|
||||
* All auto implemented public properties with public getters and setters on ASP.NET Core remote flow sources are now also considered to be tainted.
|
||||
|
||||
## 0.1.4
|
||||
|
||||
## 0.1.3
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* All auto implemented public properties with public getters and setters on ASP.NET Core remote flow sources are now also considered to be tainted.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The syntax of the (source|sink|summary)model CSV format has been changed slightly for Java and C#. A new column called `provenance` has been introduced, where the allowed values are `manual` and `generated`. The value used to indicate whether a model as been written by hand (`manual`) or create by the CSV model generator (`generated`).
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: queryMetadata
|
||||
---
|
||||
* The `kind` query metadata was changed to `diagnostic` on `cs/compilation-error`, `cs/compilation-message`, `cs/extraction-error`, and `cs/extraction-message`.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* Contextual queries and the query libraries they depend on have been moved to the `codeql/csharp-all` package.
|
||||
10
csharp/ql/src/change-notes/released/0.2.0.md
Normal file
10
csharp/ql/src/change-notes/released/0.2.0.md
Normal file
@@ -0,0 +1,10 @@
|
||||
## 0.2.0
|
||||
|
||||
### Query Metadata Changes
|
||||
|
||||
* The `kind` query metadata was changed to `diagnostic` on `cs/compilation-error`, `cs/compilation-message`, `cs/extraction-error`, and `cs/extraction-message`.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The syntax of the (source|sink|summary)model CSV format has been changed slightly for Java and C#. A new column called `provenance` has been introduced, where the allowed values are `manual` and `generated`. The value used to indicate whether a model as been written by hand (`manual`) or create by the CSV model generator (`generated`).
|
||||
* All auto implemented public properties with public getters and setters on ASP.NET Core remote flow sources are now also considered to be tainted.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.1.4
|
||||
lastReleaseVersion: 0.2.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-queries
|
||||
version: 0.2.0-dev
|
||||
version: 0.2.1-dev
|
||||
groups:
|
||||
- csharp
|
||||
- queries
|
||||
|
||||
@@ -135,6 +135,47 @@ pack names and use the ``--download`` flag::
|
||||
The ``analyze`` command above runs the default suite from ``microsoft/coding-standards v1.0.0`` and the latest version of ``github/security-queries`` on the specified database.
|
||||
For further information about default suites, see ":ref:`Publishing and using CodeQL packs <publishing-and-using-codeql-packs>`".
|
||||
|
||||
Running a subset of queries in a CodeQL pack
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you are using CodeQL CLI v2.8.1 or later, you can include a path at the end of a pack specification to run a subset of queries inside the pack. This applies to any command that locates or runs queries within a pack.
|
||||
|
||||
The complete way to specify a set of queries is in the form ``scope/name@range:path``, where:
|
||||
|
||||
- ``scope/name`` is the qualified name of a CodeQL pack.
|
||||
- ``range`` is a `semver range <https://docs.npmjs.com/cli/v6/using-npm/semver#ranges>`_.
|
||||
- ``path`` is a file system path to a single query, a directory containing queries, or a query suite file.
|
||||
|
||||
When you specify a ``scope/name``, the ``range`` and ``path`` are
|
||||
optional. If you omit a ``range`` then the latest version of the
|
||||
specified pack is used. If you omit a ``path`` then the default query suite
|
||||
of the specified pack is used.
|
||||
|
||||
The ``path`` can be one of a ``*.ql`` query file, a directory
|
||||
containing one or more queries, or a ``.qls`` query suite file. If
|
||||
you omit a pack name, then you must provide a ``path``,
|
||||
which will be interpreted relative to the working directory
|
||||
of the current process.
|
||||
|
||||
If you specify a ``scope/name`` and ``path``, then the ``path`` cannot
|
||||
be absolute. It is considered relative to the root of the CodeQL
|
||||
pack.
|
||||
|
||||
To analyze a database using all queries in the `experimental/Security` folder within the `codeql/cpp-queries` CodeQL pack you can use::
|
||||
|
||||
codeql database analyze --format=sarif-latest --output=results <db> \
|
||||
codeql/cpp-queries:experimental/Security
|
||||
|
||||
To run the `RedundantNullCheckParam.ql` query in the `codeql/cpp-queries` CodeQL pack use::
|
||||
|
||||
codeql database analyze --format=sarif-latest --output=results <db> \
|
||||
'codeql/cpp-queries:experimental/Likely Bugs/RedundantNullCheckParam.ql'
|
||||
|
||||
To analyze your database using the `cpp-security-and-quality.qls` query suite from a version of the `codeql/cpp-queries` CodeQL pack that is >= 0.0.3 and < 0.1.0 (the highest compatible version will be chosen) you can use::
|
||||
|
||||
codeql database analyze --format=sarif-latest --output=results <db> \
|
||||
'codeql/cpp-queries@~0.0.3:codeql-suites/cpp-security-and-quality.qls'
|
||||
|
||||
For more information about CodeQL packs, see :doc:`About CodeQL Packs <about-codeql-packs>`.
|
||||
|
||||
Running query suites
|
||||
@@ -223,7 +264,7 @@ you can include the query help for your custom queries in SARIF files generated
|
||||
After uploading the SARIF file to GitHub, the query help is shown in the code scanning UI for any
|
||||
alerts generated by the custom queries.
|
||||
|
||||
From CodeQL CLI 2.7.1 onwards, you can include markdown-rendered query help in SARIF files
|
||||
From CodeQL CLI v2.7.1 onwards, you can include markdown-rendered query help in SARIF files
|
||||
by providing the ``--sarif-add-query-help`` option when running
|
||||
``codeql database analyze``.
|
||||
For more information, see `Configuring CodeQL CLI in your CI system <https://docs.github.com/en/code-security/code-scanning/using-codeql-code-scanning-with-your-existing-ci-system/configuring-codeql-cli-in-your-ci-system#analyzing-a-codeql-database>`__
|
||||
|
||||
@@ -68,3 +68,11 @@ This command downloads all dependencies to the shared cache on the local disk.
|
||||
Note
|
||||
|
||||
Running the ``codeql pack add`` and ``codeql pack install`` commands will generate or update the ``qlpack.lock.yml`` file. This file should be checked-in to version control. The ``qlpack.lock.yml`` file contains the precise version numbers used by the pack.
|
||||
|
||||
.. pull-quote::
|
||||
|
||||
Note
|
||||
|
||||
By default ``codeql pack install`` will install dependencies from the Container registry on GitHub.com.
|
||||
You can install dependencies from a GitHub Enterprise Server Container registry by creating a ``qlconfig.yml`` file.
|
||||
For more information, see ":doc:`Publishing and using CodeQL packs <publishing-and-using-codeql-packs>`."
|
||||
|
||||
@@ -72,3 +72,53 @@ The ``analyze`` command will run the default suite of any specified CodeQL packs
|
||||
::
|
||||
|
||||
codeql <database> analyze <scope>/<pack> <scope>/<other-pack>
|
||||
|
||||
Working with CodeQL packs on GitHub Enterprise Server
|
||||
-----------------------------------------------------
|
||||
|
||||
.. pull-quote::
|
||||
|
||||
Note
|
||||
|
||||
The Container registry for GitHub Enterprise Server supports CodeQL query packs from GitHub Enterprise Server 3.6 onward.
|
||||
|
||||
By default, the CodeQL CLI expects to download CodeQL packs from and publish packs to the Container registry on GitHub.com. However, you can also work with CodeQL packs in a Container registry on GitHub Enterprise Server 3.6, and later, by creating a ``qlconfig.yml`` file to tell the CLI which Container registry to use for each pack.
|
||||
|
||||
Create a ``~/.codeql/qlconfig.yml`` file using your preferred text editor, and add entries to specify which registry to use for one or more package name patterns.
|
||||
For example, the following ``qlconfig.yml`` file associates all packs with the Container registry for the GitHub Enterprise Server at ``GHE_HOSTNAME``, except packs matching ``codeql/*``, which are associated with the Container registry on GitHub.com:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
registries:
|
||||
- packages: 'codeql/*'
|
||||
url: https://ghcr.io/v2/
|
||||
- packages: '*'
|
||||
url: https://containers.GHE_HOSTNAME/v2/
|
||||
|
||||
The CodeQL CLI will determine which registry to use for a given package name by finding the first item in the ``registries`` list with a ``packages`` property that matches that package name.
|
||||
This means that you'll generally want to define the most specific package name patterns first.
|
||||
|
||||
You can now use ``codeql pack publish``, ``codeql pack download``, and ``codeql database analyze`` to manage packs on GitHub Enterprise Server.
|
||||
|
||||
Authenticating to GitHub Container registries
|
||||
---------------------------------------------
|
||||
|
||||
You can publish packs and download private packs by authenticating to the appropriate GitHub Container registry.
|
||||
|
||||
You can authenticate to the Container registry on GitHub.com in two ways:
|
||||
|
||||
1. Pass the ``--github-auth-stdin`` option to the CodeQL CLI, then supply a GitHub Apps token or personal access token via standard input.
|
||||
2. Set the ``GITHUB_TOKEN`` environment variable to a GitHub Apps token or personal access token.
|
||||
|
||||
Similarly, you can authenticate to a GHES Container registry, or authenticate to multiple registries simultaneously (for example, to download or run private packs from multiple registries) in two ways:
|
||||
|
||||
1. Pass the ``--registries-auth-stdin`` option to the CodeQL CLI, then supply a registry authentication string via standard input.
|
||||
2. Set the ``CODEQL_REGISTRIES_AUTH`` environment variable to a registry authentication string.
|
||||
|
||||
A registry authentication string is a comma-separated list of ``<registry-url>=<token>`` pairs, where ``registry-url`` is a GitHub Container registry URL, such as ``https://containers.GHE_HOSTNAME/v2/``, and ``token`` is a GitHub Apps token or personal access token for that GitHub Container registry.
|
||||
This ensures that each token is only passed to the Container registry you specify.
|
||||
For instance, the following registry authentication string specifies that the CodeQL CLI should authenticate to the Container registry on GitHub.com using the token ``<token1>`` and to the Container registry for the GHES instance at ``GHE_HOSTNAME`` using the token ``<token2>``:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
https://ghcr.io/v2/=<token1>,https://containers.GHE_HOSTNAME/v2/=<token2>
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
Note
|
||||
|
||||
The CodeQL package management functionality, including CodeQL packs, is currently available as a beta release and is subject to change. During the beta release, CodeQL packs are available only using GitHub Packages - the GitHub Container registry. To use this beta functionality, install version 2.6.0 or higher of the CodeQL CLI bundle from: https://github.com/github/codeql-action/releases.
|
||||
The CodeQL package management functionality, including CodeQL packs, is currently available as a beta release and is subject to change. During the beta release, CodeQL packs are available only using GitHub Packages - the GitHub Container registry. To use this beta functionality, install the latest version of the CodeQL CLI bundle from: https://github.com/github/codeql-action/releases.
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.2.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
|
||||
|
||||
## 0.1.4
|
||||
|
||||
## 0.1.3
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
## 0.2.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.1.4
|
||||
lastReleaseVersion: 0.2.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/go-all
|
||||
version: 0.2.0-dev
|
||||
version: 0.2.1-dev
|
||||
groups: go
|
||||
dbscheme: go.dbscheme
|
||||
extractor: go
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 0.2.0
|
||||
|
||||
## 0.1.4
|
||||
|
||||
## 0.1.3
|
||||
|
||||
1
go/ql/src/change-notes/released/0.2.0.md
Normal file
1
go/ql/src/change-notes/released/0.2.0.md
Normal file
@@ -0,0 +1 @@
|
||||
## 0.2.0
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.1.4
|
||||
lastReleaseVersion: 0.2.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/go-queries
|
||||
version: 0.2.0-dev
|
||||
version: 0.2.1-dev
|
||||
groups:
|
||||
- go
|
||||
- queries
|
||||
|
||||
@@ -1,121 +1,121 @@
|
||||
package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:set-hostname-verifier,sink:sql,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value
|
||||
android.app,16,,103,,,,,,7,,,,,,,,,9,,,,,,,,,,,,,,,,,,18,85
|
||||
android.content,24,27,108,,,,,,16,,,,,,,,,,,,,,,,,8,,,,,,,,27,,31,77
|
||||
android.database,59,,30,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,,,30,
|
||||
android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15
|
||||
android.os,,,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,41,81
|
||||
android.util,6,16,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,16,,
|
||||
android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,2,,
|
||||
android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,1,
|
||||
androidx.slice,2,5,88,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,5,,27,61
|
||||
cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,
|
||||
com.google.common.base,4,,85,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,,62,23
|
||||
com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17
|
||||
com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551
|
||||
com.google.common.flogger,29,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,,
|
||||
com.google.common.io,6,,73,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,72,1
|
||||
com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,
|
||||
com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7,
|
||||
com.unboundid.ldap.sdk,17,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
com.zaxxer.hikari,2,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
|
||||
groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,7,,
|
||||
jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23
|
||||
jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,
|
||||
jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,
|
||||
jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,94,55
|
||||
java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
java.io,37,,39,,15,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,39,
|
||||
java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,46,12
|
||||
java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,3,7,
|
||||
java.nio,15,,6,,13,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,6,
|
||||
java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,7,,,,,,,,,,,
|
||||
java.util,44,,438,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,24,414
|
||||
javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,7,,
|
||||
javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57,
|
||||
javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23
|
||||
javax.management.remote,2,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
javax.naming,7,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,
|
||||
javax.script,1,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,
|
||||
javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,,,,,,,,,,,,,21,2,
|
||||
javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,
|
||||
javax.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,
|
||||
javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,
|
||||
javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,94,55
|
||||
javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,6,
|
||||
javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,
|
||||
jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10
|
||||
kotlin.jvm.internal,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
|
||||
net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,,
|
||||
ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,
|
||||
okhttp3,2,,47,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,22,25
|
||||
org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,
|
||||
org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783
|
||||
org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783
|
||||
org.apache.commons.io,104,,561,,89,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,547,14
|
||||
org.apache.commons.jexl2,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.commons.jexl3,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.commons.lang3,,,424,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,293,131
|
||||
org.apache.commons.logging,6,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.commons.ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52
|
||||
org.apache.directory.ldap.client.api,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,2,39,
|
||||
org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,
|
||||
org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6
|
||||
org.apache.http,27,3,70,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,2,,,3,62,8
|
||||
org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,57,
|
||||
org.apache.log4j,11,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.logging.log4j,359,,8,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,4,4
|
||||
org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
org.apache.shiro.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,,
|
||||
org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,
|
||||
org.jboss.logging,324,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.jdbi.v3.core,6,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,
|
||||
org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38
|
||||
org.mvel2,16,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.scijava.log,13,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.slf4j,55,,6,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,2,4
|
||||
org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30
|
||||
org.springframework.boot.jdbc,1,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13
|
||||
org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,
|
||||
org.springframework.http,14,,70,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,,,,,60,10
|
||||
org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,,
|
||||
org.springframework.jdbc.datasource,4,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,
|
||||
org.springframework.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.springframework.ldap,47,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,
|
||||
org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32
|
||||
org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,87,52
|
||||
org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13,
|
||||
org.springframework.web.client,13,3,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,3,,
|
||||
org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,,
|
||||
org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13,
|
||||
org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,
|
||||
org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,138,25
|
||||
org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,
|
||||
play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,
|
||||
ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,
|
||||
ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4,
|
||||
ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10,
|
||||
ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48
|
||||
ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,
|
||||
ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35
|
||||
ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4,
|
||||
ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10,
|
||||
ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35
|
||||
retrofit2,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,
|
||||
package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:set-hostname-verifier,sink:sql,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-external-storage-dir,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value
|
||||
android.app,16,,103,,,,,,7,,,,,,,,,9,,,,,,,,,,,,,,,,,,,18,85
|
||||
android.content,24,31,108,,,,,,16,,,,,,,,,,,,,,,,,8,,,,,,,4,,27,,31,77
|
||||
android.database,59,,30,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,,,,30,
|
||||
android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15
|
||||
android.os,,2,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,41,81
|
||||
android.util,6,16,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,16,,
|
||||
android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,2,,
|
||||
android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,1,
|
||||
androidx.slice,2,5,88,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,5,,27,61
|
||||
cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,
|
||||
com.google.common.base,4,,85,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,,,62,23
|
||||
com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17
|
||||
com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551
|
||||
com.google.common.flogger,29,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
com.google.common.io,6,,73,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,72,1
|
||||
com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,,
|
||||
com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7,
|
||||
com.unboundid.ldap.sdk,17,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
com.zaxxer.hikari,2,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
|
||||
groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,,
|
||||
jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23
|
||||
jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,
|
||||
jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,
|
||||
jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55
|
||||
java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
java.io,37,,39,,15,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,,39,
|
||||
java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,46,12
|
||||
java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,3,7,
|
||||
java.nio,15,,6,,13,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,6,
|
||||
java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,7,,,,,,,,,,,,
|
||||
java.util,44,,438,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,,24,414
|
||||
javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,,
|
||||
javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57,
|
||||
javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23
|
||||
javax.management.remote,2,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
javax.naming,7,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,
|
||||
javax.script,1,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,
|
||||
javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,2,
|
||||
javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,
|
||||
javax.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,
|
||||
javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,
|
||||
javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55
|
||||
javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,6,
|
||||
javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,,
|
||||
jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10
|
||||
kotlin.jvm.internal,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
|
||||
net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,,,
|
||||
ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,
|
||||
okhttp3,2,,47,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,22,25
|
||||
org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,
|
||||
org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783
|
||||
org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783
|
||||
org.apache.commons.io,104,,561,,89,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,547,14
|
||||
org.apache.commons.jexl2,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.commons.jexl3,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.commons.lang3,,,424,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,293,131
|
||||
org.apache.commons.logging,6,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.commons.ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52
|
||||
org.apache.directory.ldap.client.api,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,2,39,
|
||||
org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,
|
||||
org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6
|
||||
org.apache.http,27,3,70,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,2,,,,3,62,8
|
||||
org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,57,
|
||||
org.apache.log4j,11,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.apache.logging.log4j,359,,8,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,,4,4
|
||||
org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
org.apache.shiro.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,,,
|
||||
org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,
|
||||
org.jboss.logging,324,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.jdbi.v3.core,6,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,
|
||||
org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38
|
||||
org.mvel2,16,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.scijava.log,13,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.slf4j,55,,6,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,,2,4
|
||||
org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30
|
||||
org.springframework.boot.jdbc,1,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13
|
||||
org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,
|
||||
org.springframework.http,14,,70,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,,,,,,60,10
|
||||
org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,,,
|
||||
org.springframework.jdbc.datasource,4,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,
|
||||
org.springframework.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.springframework.ldap,47,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,,
|
||||
org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32
|
||||
org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,87,52
|
||||
org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13,
|
||||
org.springframework.web.client,13,3,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,3,,
|
||||
org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,,
|
||||
org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13,
|
||||
org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,
|
||||
org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,138,25
|
||||
org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
|
||||
org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,
|
||||
play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,
|
||||
ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,
|
||||
ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4,
|
||||
ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10,
|
||||
ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48
|
||||
ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,
|
||||
ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35
|
||||
ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4,
|
||||
ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10,
|
||||
ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35
|
||||
retrofit2,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,
|
||||
|
||||
|
@@ -7,7 +7,7 @@ Java framework & library support
|
||||
:widths: auto
|
||||
|
||||
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE‑022` :sub:`Path injection`,`CWE‑036` :sub:`Path traversal`,`CWE‑079` :sub:`Cross-site scripting`,`CWE‑089` :sub:`SQL injection`,`CWE‑090` :sub:`LDAP injection`,`CWE‑094` :sub:`Code injection`,`CWE‑319` :sub:`Cleartext transmission`
|
||||
Android,``android.*``,46,424,108,,,3,67,,,
|
||||
Android,``android.*``,52,424,108,,,3,67,,,
|
||||
`Apache Commons Collections <https://commons.apache.org/proper/commons-collections/>`_,"``org.apache.commons.collections``, ``org.apache.commons.collections4``",,1600,,,,,,,,
|
||||
`Apache Commons IO <https://commons.apache.org/proper/commons-io/>`_,``org.apache.commons.io``,,561,104,89,,,,,,15
|
||||
`Apache Commons Lang <https://commons.apache.org/proper/commons-lang/>`_,``org.apache.commons.lang3``,,424,,,,,,,,
|
||||
@@ -19,5 +19,5 @@ Java framework & library support
|
||||
Java extensions,"``javax.*``, ``jakarta.*``",63,609,32,,,4,,1,1,2
|
||||
`Spring <https://spring.io/>`_,``org.springframework.*``,29,476,101,,,,19,14,,29
|
||||
Others,"``androidx.slice``, ``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``kotlin.jvm.internal``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.logging.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jboss.logging``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",65,395,932,,,,14,18,,3
|
||||
Totals,,211,6410,1474,117,6,10,107,33,1,84
|
||||
Totals,,217,6410,1474,117,6,10,107,33,1,84
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.github.codeql.utils.versions.functionN
|
||||
import com.github.codeql.utils.versions.getIrStubFromDescriptor
|
||||
import com.semmle.extractor.java.OdasaOutput
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.backend.common.lower.parents
|
||||
import org.jetbrains.kotlin.backend.common.pop
|
||||
import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
@@ -80,7 +81,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
file.declarations.map { extractDeclaration(it, extractPrivateMembers = true, extractFunctionBodies = true) }
|
||||
file.declarations.forEach { extractDeclaration(it, extractPrivateMembers = true, extractFunctionBodies = true) }
|
||||
extractStaticInitializer(file, null)
|
||||
CommentExtractor(this, file, tw.fileId).extract()
|
||||
}
|
||||
@@ -133,7 +134,7 @@ open class KotlinFileExtractor(
|
||||
is IrProperty -> {
|
||||
val parentId = useDeclarationParent(declaration.parent, false)?.cast<DbReftype>()
|
||||
if (parentId != null) {
|
||||
extractProperty(declaration, parentId, extractBackingField = true, extractFunctionBodies = extractFunctionBodies, null, listOf())
|
||||
extractProperty(declaration, parentId, extractBackingField = true, extractFunctionBodies = extractFunctionBodies, extractPrivateMembers = extractPrivateMembers, null, listOf())
|
||||
}
|
||||
Unit
|
||||
}
|
||||
@@ -181,7 +182,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractTypeParameter(tp: IrTypeParameter, apparentIndex: Int, javaTypeParameter: JavaTypeParameter?): Label<out DbTypevariable>? {
|
||||
private fun extractTypeParameter(tp: IrTypeParameter, apparentIndex: Int, javaTypeParameter: JavaTypeParameter?): Label<out DbTypevariable>? {
|
||||
with("type parameter", tp) {
|
||||
val parentId = getTypeParameterParentLabel(tp) ?: return null
|
||||
val id = tw.getLabelFor<DbTypevariable>(getTypeParameterLabel(tp))
|
||||
@@ -216,7 +217,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractVisibility(elementForLocation: IrElement, id: Label<out DbModifiable>, v: DescriptorVisibility) {
|
||||
private fun extractVisibility(elementForLocation: IrElement, id: Label<out DbModifiable>, v: DescriptorVisibility) {
|
||||
with("visibility", elementForLocation) {
|
||||
when (v) {
|
||||
DescriptorVisibilities.PRIVATE -> addModifiers(id, "private")
|
||||
@@ -250,7 +251,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractClassModifiers(c: IrClass, id: Label<out DbClassorinterface>) {
|
||||
private fun extractClassModifiers(c: IrClass, id: Label<out DbClassorinterface>) {
|
||||
with("class modifiers", c) {
|
||||
when (c.modality) {
|
||||
Modality.FINAL -> addModifiers(id, "final")
|
||||
@@ -314,8 +315,21 @@ open class KotlinFileExtractor(
|
||||
val locId = getLocation(c, argsIncludingOuterClasses)
|
||||
tw.writeHasLocation(id, locId)
|
||||
|
||||
// Extract the outer <-> inner class relationship, passing on any type arguments in excess to this class' parameters.
|
||||
extractEnclosingClass(c, id, locId, argsIncludingOuterClasses?.drop(c.typeParameters.size) ?: listOf())
|
||||
// Extract the outer <-> inner class relationship, passing on any type arguments in excess to this class' parameters if this is an inner class.
|
||||
// For example, in `class Outer<T> { inner class Inner<S> { } }`, `Inner<Int, String>` nests within `Outer<Int>` and raw `Inner<>` within `Outer<>`,
|
||||
// but for a similar non-`inner` (in Java terms, static nested) class both `Inner<Int>` and `Inner<>` nest within the unbound type `Outer`.
|
||||
val useBoundOuterType = (c.isInner || c.isLocal) && (c.parents.map { // Would use `firstNotNullOfOrNull`, but this doesn't exist in Kotlin 1.4
|
||||
when(it) {
|
||||
is IrClass -> when {
|
||||
it.typeParameters.isNotEmpty() -> true // Type parameters visible to this class -- extract an enclosing bound or raw type.
|
||||
!(it.isInner || it.isLocal) -> false // No type parameters seen yet, and this is a static class -- extract an enclosing unbound type.
|
||||
else -> null // No type parameters seen here, but may be visible enclosing type parameters; keep searching.
|
||||
}
|
||||
else -> null // Look through enclosing non-class entities (this may need to change)
|
||||
}
|
||||
}.firstOrNull { it != null } ?: false)
|
||||
|
||||
extractEnclosingClass(c, id, locId, if (useBoundOuterType) argsIncludingOuterClasses?.drop(c.typeParameters.size) else listOf())
|
||||
|
||||
return id
|
||||
}
|
||||
@@ -350,7 +364,7 @@ open class KotlinFileExtractor(
|
||||
if (shouldExtractDecl(it, false)) {
|
||||
when(it) {
|
||||
is IrFunction -> extractFunction(it, id, extractBody = false, extractMethodAndParameterTypeAccesses = false, typeParamSubstitution, argsIncludingOuterClasses)
|
||||
is IrProperty -> extractProperty(it, id, extractBackingField = false, extractFunctionBodies = false, typeParamSubstitution, argsIncludingOuterClasses)
|
||||
is IrProperty -> extractProperty(it, id, extractBackingField = false, extractFunctionBodies = false, extractPrivateMembers = false, typeParamSubstitution, argsIncludingOuterClasses)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@@ -371,7 +385,7 @@ open class KotlinFileExtractor(
|
||||
tw.writeHasLocation(stmtId, locId)
|
||||
}
|
||||
|
||||
fun extractObinitFunction(c: IrClass, parentId: Label<out DbClassorinterface>) {
|
||||
private fun extractObinitFunction(c: IrClass, parentId: Label<out DbClassorinterface>) {
|
||||
// add method:
|
||||
val obinitLabel = getObinitLabel(c)
|
||||
val obinitId = tw.getLabelFor<DbMethod>(obinitLabel)
|
||||
@@ -392,6 +406,8 @@ open class KotlinFileExtractor(
|
||||
extractDeclInitializers(c.declarations, false) { Pair(blockId, obinitId) }
|
||||
}
|
||||
|
||||
val jvmStaticFqName = FqName("kotlin.jvm.JvmStatic")
|
||||
|
||||
fun extractClassSource(c: IrClass, extractDeclarations: Boolean, extractStaticInitializer: Boolean, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean): Label<out DbClassorinterface> {
|
||||
with("class source", c) {
|
||||
DeclarationStackAdjuster(c).use {
|
||||
@@ -428,9 +444,10 @@ open class KotlinFileExtractor(
|
||||
|
||||
c.typeParameters.mapIndexed { idx, param -> extractTypeParameter(param, idx, javaClass?.typeParameters?.getOrNull(idx)) }
|
||||
if (extractDeclarations) {
|
||||
c.declarations.map { extractDeclaration(it, extractPrivateMembers = extractPrivateMembers, extractFunctionBodies = extractFunctionBodies) }
|
||||
c.declarations.forEach { extractDeclaration(it, extractPrivateMembers = extractPrivateMembers, extractFunctionBodies = extractFunctionBodies) }
|
||||
if (extractStaticInitializer)
|
||||
extractStaticInitializer(c, id)
|
||||
extractJvmStaticProxyMethods(c, id, extractPrivateMembers, extractFunctionBodies)
|
||||
}
|
||||
if (c.isNonCompanionObject) {
|
||||
// For `object MyObject { ... }`, the .class has an
|
||||
@@ -458,7 +475,78 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractEnclosingClass(innerDeclaration: IrDeclaration, innerId: Label<out DbClassorinterface>, innerLocId: Label<DbLocation>, parentClassTypeArguments: List<IrTypeArgument>) {
|
||||
private fun extractJvmStaticProxyMethods(c: IrClass, classId: Label<out DbClassorinterface>, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean) {
|
||||
|
||||
// Add synthetic forwarders for any JvmStatic methods or properties:
|
||||
val companionObject = c.companionObject() ?: return
|
||||
|
||||
val cType = c.typeWith()
|
||||
val companionType = companionObject.typeWith()
|
||||
|
||||
fun makeProxyFunction(f: IrFunction) {
|
||||
// Emit a function in class `c` that delegates to the same function defined on `c.CompanionInstance`.
|
||||
val proxyFunctionId = tw.getLabelFor<DbMethod>(getFunctionLabel(f, classId, listOf()))
|
||||
// We extract the function prototype with its ID overridden to belong to `c` not the companion object,
|
||||
// but suppress outputting the body, which we will replace with a delegating call below.
|
||||
forceExtractFunction(f, classId, extractBody = false, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution = null, classTypeArgsIncludingOuterClasses = listOf(), idOverride = proxyFunctionId, locOverride = null, extractOrigin = false)
|
||||
addModifiers(proxyFunctionId, "static")
|
||||
tw.writeCompiler_generated(proxyFunctionId, CompilerGeneratedKinds.JVMSTATIC_PROXY_METHOD.kind)
|
||||
if (extractFunctionBodies) {
|
||||
val realFunctionLocId = tw.getLocation(f)
|
||||
extractExpressionBody(proxyFunctionId, realFunctionLocId).also { returnId ->
|
||||
extractRawMethodAccess(
|
||||
f,
|
||||
realFunctionLocId,
|
||||
f.returnType,
|
||||
proxyFunctionId,
|
||||
returnId,
|
||||
0,
|
||||
returnId,
|
||||
f.valueParameters.size,
|
||||
{ argParent, idxOffset ->
|
||||
f.valueParameters.forEachIndexed { idx, param ->
|
||||
val syntheticParamId = useValueParameter(param, proxyFunctionId)
|
||||
extractVariableAccess(syntheticParamId, param.type, realFunctionLocId, argParent, idxOffset + idx, proxyFunctionId, returnId)
|
||||
}
|
||||
},
|
||||
companionType,
|
||||
{ callId ->
|
||||
val companionField = useCompanionObjectClassInstance(companionObject)?.id
|
||||
extractVariableAccess(companionField, companionType, realFunctionLocId, callId, -1, proxyFunctionId, returnId).also { varAccessId ->
|
||||
extractTypeAccessRecursive(cType, realFunctionLocId, varAccessId, -1, proxyFunctionId, returnId)
|
||||
}
|
||||
},
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companionObject.declarations.forEach {
|
||||
if (shouldExtractDecl(it, extractPrivateMembers)) {
|
||||
val wholeDeclAnnotated = it.hasAnnotation(jvmStaticFqName)
|
||||
when(it) {
|
||||
is IrFunction -> {
|
||||
if (wholeDeclAnnotated)
|
||||
makeProxyFunction(it)
|
||||
}
|
||||
is IrProperty -> {
|
||||
it.getter?.let { getter ->
|
||||
if (wholeDeclAnnotated || getter.hasAnnotation(jvmStaticFqName))
|
||||
makeProxyFunction(getter)
|
||||
}
|
||||
it.setter?.let { setter ->
|
||||
if (wholeDeclAnnotated || setter.hasAnnotation(jvmStaticFqName))
|
||||
makeProxyFunction(setter)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If `parentClassTypeArguments` is null, the parent class is a raw type.
|
||||
private fun extractEnclosingClass(innerDeclaration: IrDeclaration, innerId: Label<out DbClassorinterface>, innerLocId: Label<DbLocation>, parentClassTypeArguments: List<IrTypeArgument>?) {
|
||||
with("enclosing class", innerDeclaration) {
|
||||
var parent: IrDeclarationParent? = innerDeclaration.parent
|
||||
while (parent != null) {
|
||||
@@ -506,7 +594,7 @@ open class KotlinFileExtractor(
|
||||
|
||||
data class FieldResult(val id: Label<DbField>, val name: String)
|
||||
|
||||
fun useCompanionObjectClassInstance(c: IrClass): FieldResult? {
|
||||
private fun useCompanionObjectClassInstance(c: IrClass): FieldResult? {
|
||||
val parent = c.parent
|
||||
if(!c.isCompanion) {
|
||||
logger.error("Using companion instance for non-companion class")
|
||||
@@ -524,7 +612,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun useObjectClassInstance(c: IrClass): FieldResult {
|
||||
private fun useObjectClassInstance(c: IrClass): FieldResult {
|
||||
if(!c.isNonCompanionObject) {
|
||||
logger.error("Using instance for non-object class")
|
||||
}
|
||||
@@ -719,13 +807,13 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) =
|
||||
private fun extractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) =
|
||||
if (isFake(f))
|
||||
null
|
||||
else
|
||||
forceExtractFunction(f, parentId, extractBody, extractMethodAndParameterTypeAccesses, typeSubstitution, classTypeArgsIncludingOuterClasses, null, null)
|
||||
|
||||
fun forceExtractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, idOverride: Label<DbMethod>?, locOverride: Label<DbLocation>?): Label<out DbCallable> {
|
||||
private fun forceExtractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, idOverride: Label<DbMethod>?, locOverride: Label<DbLocation>?, extractOrigin: Boolean = true): Label<out DbCallable> {
|
||||
with("function", f) {
|
||||
DeclarationStackAdjuster(f).use {
|
||||
|
||||
@@ -782,13 +870,15 @@ open class KotlinFileExtractor(
|
||||
val methodId = id.cast<DbMethod>()
|
||||
tw.writeMethods(methodId, shortName.nameInDB, "${shortName.nameInDB}$paramsSignature", returnType.javaResult.id, parentId, sourceDeclaration.cast<DbMethod>())
|
||||
tw.writeMethodsKotlinType(methodId, returnType.kotlinResult.id)
|
||||
when (f.origin) {
|
||||
IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER ->
|
||||
tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.GENERATED_DATA_CLASS_MEMBER.kind)
|
||||
IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR ->
|
||||
tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.DEFAULT_PROPERTY_ACCESSOR.kind)
|
||||
IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER ->
|
||||
tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.ENUM_CLASS_SPECIAL_MEMBER.kind)
|
||||
if (extractOrigin) {
|
||||
when (f.origin) {
|
||||
IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER ->
|
||||
tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.GENERATED_DATA_CLASS_MEMBER.kind)
|
||||
IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR ->
|
||||
tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.DEFAULT_PROPERTY_ACCESSOR.kind)
|
||||
IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER ->
|
||||
tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.ENUM_CLASS_SPECIAL_MEMBER.kind)
|
||||
}
|
||||
}
|
||||
|
||||
if (extractMethodAndParameterTypeAccesses) {
|
||||
@@ -809,10 +899,13 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
|
||||
extractVisibility(f, id, f.visibility)
|
||||
if (isStaticFunction(f)) {
|
||||
|
||||
if (f.isInline) {
|
||||
addModifiers(id, "inline")
|
||||
}
|
||||
if (f.shouldExtractAsStatic) {
|
||||
addModifiers(id, "static")
|
||||
}
|
||||
|
||||
if (f is IrSimpleFunction && f.overriddenSymbols.isNotEmpty()) {
|
||||
addModifiers(id, "override")
|
||||
}
|
||||
@@ -828,7 +921,7 @@ open class KotlinFileExtractor(
|
||||
&& f.symbol !is IrConstructorSymbol // not a constructor
|
||||
}
|
||||
|
||||
fun extractField(f: IrField, parentId: Label<out DbReftype>): Label<out DbField> {
|
||||
private fun extractField(f: IrField, parentId: Label<out DbReftype>): Label<out DbField> {
|
||||
with("field", f) {
|
||||
DeclarationStackAdjuster(f).use {
|
||||
declarationStack.push(f)
|
||||
@@ -862,7 +955,7 @@ open class KotlinFileExtractor(
|
||||
return id
|
||||
}
|
||||
|
||||
fun extractProperty(p: IrProperty, parentId: Label<out DbReftype>, extractBackingField: Boolean, extractFunctionBodies: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) {
|
||||
private fun extractProperty(p: IrProperty, parentId: Label<out DbReftype>, extractBackingField: Boolean, extractFunctionBodies: Boolean, extractPrivateMembers: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) {
|
||||
with("property", p) {
|
||||
if (isFake(p)) return
|
||||
|
||||
@@ -877,28 +970,34 @@ open class KotlinFileExtractor(
|
||||
val getter = p.getter
|
||||
val setter = p.setter
|
||||
|
||||
if (getter != null) {
|
||||
val getterId = extractFunction(getter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast<DbMethod>()
|
||||
if (getterId != null) {
|
||||
tw.writeKtPropertyGetters(id, getterId)
|
||||
}
|
||||
} else {
|
||||
if (getter == null) {
|
||||
if (p.modality != Modality.FINAL || !isExternalDeclaration(p)) {
|
||||
logger.warnElement("IrProperty without a getter", p)
|
||||
}
|
||||
} else if (shouldExtractDecl(getter, extractPrivateMembers)) {
|
||||
val getterId = extractFunction(getter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast<DbMethod>()
|
||||
if (getterId != null) {
|
||||
tw.writeKtPropertyGetters(id, getterId)
|
||||
if (getter.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR) {
|
||||
tw.writeCompiler_generated(getterId, CompilerGeneratedKinds.DELEGATED_PROPERTY_GETTER.kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (setter != null) {
|
||||
if (setter == null) {
|
||||
if (p.isVar && !isExternalDeclaration(p)) {
|
||||
logger.warnElement("isVar property without a setter", p)
|
||||
}
|
||||
} else if (shouldExtractDecl(setter, extractPrivateMembers)) {
|
||||
if (!p.isVar) {
|
||||
logger.warnElement("!isVar property with a setter", p)
|
||||
}
|
||||
val setterId = extractFunction(setter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast<DbMethod>()
|
||||
if (setterId != null) {
|
||||
tw.writeKtPropertySetters(id, setterId)
|
||||
}
|
||||
} else {
|
||||
if (p.isVar && !isExternalDeclaration(p)) {
|
||||
logger.warnElement("isVar property without a setter", p)
|
||||
if (setter.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR) {
|
||||
tw.writeCompiler_generated(setterId, CompilerGeneratedKinds.DELEGATED_PROPERTY_SETTER.kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -931,7 +1030,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractEnumEntry(ee: IrEnumEntry, parentId: Label<out DbReftype>, extractTypeAccess: Boolean) {
|
||||
private fun extractEnumEntry(ee: IrEnumEntry, parentId: Label<out DbReftype>, extractTypeAccess: Boolean) {
|
||||
with("enum entry", ee) {
|
||||
DeclarationStackAdjuster(ee).use {
|
||||
val id = useEnumEntry(ee)
|
||||
@@ -953,7 +1052,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractTypeAlias(ta: IrTypeAlias) {
|
||||
private fun extractTypeAlias(ta: IrTypeAlias) {
|
||||
with("type alias", ta) {
|
||||
if (ta.typeParameters.isNotEmpty()) {
|
||||
// TODO: Extract this information
|
||||
@@ -968,7 +1067,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractBody(b: IrBody, callable: Label<out DbCallable>) {
|
||||
private fun extractBody(b: IrBody, callable: Label<out DbCallable>) {
|
||||
with("body", b) {
|
||||
when (b) {
|
||||
is IrBlockBody -> extractBlockBody(b, callable)
|
||||
@@ -981,7 +1080,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractBlockBody(b: IrBlockBody, callable: Label<out DbCallable>) {
|
||||
private fun extractBlockBody(b: IrBlockBody, callable: Label<out DbCallable>) {
|
||||
with("block body", b) {
|
||||
val id = tw.getFreshIdLabel<DbBlock>()
|
||||
val locId = tw.getLocation(b)
|
||||
@@ -993,7 +1092,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractSyntheticBody(b: IrSyntheticBody, callable: Label<out DbCallable>) {
|
||||
private fun extractSyntheticBody(b: IrSyntheticBody, callable: Label<out DbCallable>) {
|
||||
with("synthetic body", b) {
|
||||
when (b.kind) {
|
||||
IrSyntheticBodyKind.ENUM_VALUES -> tw.writeKtSyntheticBody(callable, 1)
|
||||
@@ -1002,17 +1101,23 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractExpressionBody(b: IrExpressionBody, callable: Label<out DbCallable>) {
|
||||
private fun extractExpressionBody(b: IrExpressionBody, callable: Label<out DbCallable>) {
|
||||
with("expression body", b) {
|
||||
val blockId = tw.getFreshIdLabel<DbBlock>()
|
||||
val locId = tw.getLocation(b)
|
||||
tw.writeStmts_block(blockId, callable, 0, callable)
|
||||
tw.writeHasLocation(blockId, locId)
|
||||
extractExpressionBody(callable, locId).also { returnId ->
|
||||
extractExpressionExpr(b.expression, callable, returnId, 0, returnId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val returnId = tw.getFreshIdLabel<DbReturnstmt>()
|
||||
fun extractExpressionBody(callable: Label<out DbCallable>, locId: Label<out DbLocation>): Label<out DbStmt> {
|
||||
val blockId = tw.getFreshIdLabel<DbBlock>()
|
||||
tw.writeStmts_block(blockId, callable, 0, callable)
|
||||
tw.writeHasLocation(blockId, locId)
|
||||
|
||||
return tw.getFreshIdLabel<DbReturnstmt>().also { returnId ->
|
||||
tw.writeStmts_returnstmt(returnId, blockId, 0, callable)
|
||||
tw.writeHasLocation(returnId, locId)
|
||||
extractExpressionExpr(b.expression, callable, returnId, 0, returnId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1026,7 +1131,7 @@ open class KotlinFileExtractor(
|
||||
return v
|
||||
}
|
||||
|
||||
fun extractVariable(v: IrVariable, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
|
||||
private fun extractVariable(v: IrVariable, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
|
||||
with("variable", v) {
|
||||
val stmtId = tw.getFreshIdLabel<DbLocalvariabledeclstmt>()
|
||||
val locId = tw.getLocation(getVariableLocationProvider(v))
|
||||
@@ -1036,7 +1141,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractVariableExpr(v: IrVariable, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
|
||||
private fun extractVariableExpr(v: IrVariable, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
|
||||
with("variable expr", v) {
|
||||
val varId = useVariable(v)
|
||||
val exprId = tw.getFreshIdLabel<DbLocalvariabledeclexpr>()
|
||||
@@ -1060,7 +1165,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractStatement(s: IrStatement, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
|
||||
private fun extractStatement(s: IrStatement, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
|
||||
with("statement", s) {
|
||||
when(s) {
|
||||
is IrExpression -> {
|
||||
@@ -1283,10 +1388,48 @@ open class KotlinFileExtractor(
|
||||
typeArguments: List<IrType> = listOf(),
|
||||
extractClassTypeArguments: Boolean = false) {
|
||||
|
||||
val locId = tw.getLocation(callsite)
|
||||
|
||||
extractRawMethodAccess(
|
||||
syntacticCallTarget,
|
||||
locId,
|
||||
callsite.type,
|
||||
enclosingCallable,
|
||||
callsiteParent,
|
||||
childIdx,
|
||||
enclosingStmt,
|
||||
valueArguments.size,
|
||||
{ argParent, idxOffset -> extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset) },
|
||||
dispatchReceiver?.type,
|
||||
dispatchReceiver?.let { { callId -> extractExpressionExpr(dispatchReceiver, enclosingCallable, callId, -1, enclosingStmt) } },
|
||||
extensionReceiver?.let { { argParent -> extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) } },
|
||||
typeArguments,
|
||||
extractClassTypeArguments
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun extractRawMethodAccess(
|
||||
syntacticCallTarget: IrFunction,
|
||||
locId: Label<DbLocation>,
|
||||
returnType: IrType,
|
||||
enclosingCallable: Label<out DbCallable>,
|
||||
callsiteParent: Label<out DbExprparent>,
|
||||
childIdx: Int,
|
||||
enclosingStmt: Label<out DbStmt>,
|
||||
nValueArguments: Int,
|
||||
extractValueArguments: (Label<out DbExpr>, Int) -> Unit,
|
||||
drType: IrType?,
|
||||
extractDispatchReceiver: ((Label<out DbExpr>) -> Unit)?,
|
||||
extractExtensionReceiver: ((Label<out DbExpr>) -> Unit)?,
|
||||
typeArguments: List<IrType> = listOf(),
|
||||
extractClassTypeArguments: Boolean = false) {
|
||||
|
||||
val callTarget = syntacticCallTarget.target.realOverrideTarget
|
||||
val id = tw.getFreshIdLabel<DbMethodaccess>()
|
||||
val type = useType(callsite.type)
|
||||
val locId = tw.getLocation(callsite)
|
||||
val type = useType(returnType)
|
||||
|
||||
tw.writeExprs_methodaccess(id, type.javaResult.id, callsiteParent, childIdx)
|
||||
tw.writeExprsKotlinType(id, type.kotlinResult.id)
|
||||
tw.writeHasLocation(id, locId)
|
||||
@@ -1296,8 +1439,6 @@ open class KotlinFileExtractor(
|
||||
// type arguments at index -2, -3, ...
|
||||
extractTypeArguments(typeArguments, locId, id, enclosingCallable, enclosingStmt, -2, true)
|
||||
|
||||
val drType = dispatchReceiver?.type
|
||||
|
||||
val isFunctionInvoke = drType != null
|
||||
&& drType is IrSimpleType
|
||||
&& drType.isFunctionOrKFunction()
|
||||
@@ -1340,44 +1481,48 @@ open class KotlinFileExtractor(
|
||||
|
||||
tw.writeCallableBinding(id, methodId)
|
||||
|
||||
if (dispatchReceiver != null) {
|
||||
extractExpressionExpr(dispatchReceiver, enclosingCallable, id, -1, enclosingStmt)
|
||||
} else if (isStaticFunction(callTarget)) {
|
||||
if (callTarget.shouldExtractAsStatic) {
|
||||
extractStaticTypeAccessQualifier(callTarget, id, locId, enclosingCallable, enclosingStmt)
|
||||
} else if (extractDispatchReceiver != null) {
|
||||
extractDispatchReceiver(id)
|
||||
}
|
||||
}
|
||||
|
||||
val idxOffset = if (extensionReceiver != null) 1 else 0
|
||||
val idxOffset = if (extractExtensionReceiver != null) 1 else 0
|
||||
|
||||
val argParent = if (isBigArityFunctionInvoke) {
|
||||
extractArrayCreationWithInitializer(id, valueArguments.size + idxOffset, locId, enclosingCallable, enclosingStmt)
|
||||
extractArrayCreationWithInitializer(id, nValueArguments + idxOffset, locId, enclosingCallable, enclosingStmt)
|
||||
} else {
|
||||
id
|
||||
}
|
||||
|
||||
if (extensionReceiver != null) {
|
||||
extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt)
|
||||
if (extractExtensionReceiver != null) {
|
||||
extractExtensionReceiver(argParent)
|
||||
}
|
||||
|
||||
extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset)
|
||||
extractValueArguments(argParent, idxOffset)
|
||||
}
|
||||
|
||||
private fun extractStaticTypeAccessQualifier(target: IrDeclaration, parentExpr: Label<out DbExprparent>, locId: Label<DbLocation>, enclosingCallable: Label<out DbCallable>, enclosingStmt: Label<out DbStmt>) {
|
||||
if (target.isStaticOfClass) {
|
||||
if (target.shouldExtractAsStaticMemberOfClass) {
|
||||
extractTypeAccessRecursive(target.parentAsClass.toRawType(), locId, parentExpr, -1, enclosingCallable, enclosingStmt)
|
||||
} else if (target.isStaticOfFile) {
|
||||
} else if (target.shouldExtractAsStaticMemberOfFile) {
|
||||
extractTypeAccess(useFileClassType(target.parent as IrFile), locId, parentExpr, -1, enclosingCallable, enclosingStmt)
|
||||
}
|
||||
}
|
||||
|
||||
private val IrDeclaration.isStaticOfClass: Boolean
|
||||
get() = this.isStatic && parent is IrClass
|
||||
private val IrDeclaration.shouldExtractAsStaticMemberOfClass: Boolean
|
||||
get() = this.shouldExtractAsStatic && parent is IrClass
|
||||
|
||||
private val IrDeclaration.isStaticOfFile: Boolean
|
||||
get() = this.isStatic && parent is IrFile
|
||||
private val IrDeclaration.shouldExtractAsStaticMemberOfFile: Boolean
|
||||
get() = this.shouldExtractAsStatic && parent is IrFile
|
||||
|
||||
private val IrDeclaration.isStatic: Boolean
|
||||
get() = this is IrSimpleFunction && dispatchReceiverParameter == null ||
|
||||
private fun isStaticAnnotatedNonCompanionMember(f: IrSimpleFunction) =
|
||||
f.parentClassOrNull?.isNonCompanionObject == true &&
|
||||
(f.hasAnnotation(jvmStaticFqName) || f.correspondingPropertySymbol?.owner?.hasAnnotation(jvmStaticFqName) == true)
|
||||
|
||||
private val IrDeclaration.shouldExtractAsStatic: Boolean
|
||||
get() = this is IrSimpleFunction && (isStaticFunction(this) || isStaticAnnotatedNonCompanionMember(this)) ||
|
||||
this is IrField && this.isStatic ||
|
||||
this is IrEnumEntry
|
||||
|
||||
@@ -1399,7 +1544,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun findFunction(cls: IrClass, name: String): IrFunction? = cls.declarations.find { it is IrFunction && it.name.asString() == name } as IrFunction?
|
||||
private fun findFunction(cls: IrClass, name: String): IrFunction? = cls.declarations.find { it is IrFunction && it.name.asString() == name } as IrFunction?
|
||||
|
||||
val jvmIntrinsicsClass by lazy {
|
||||
val result = pluginContext.referenceClass(FqName("kotlin.jvm.internal.Intrinsics"))?.owner
|
||||
@@ -1407,7 +1552,7 @@ open class KotlinFileExtractor(
|
||||
result
|
||||
}
|
||||
|
||||
fun findJdkIntrinsicOrWarn(name: String, warnAgainstElement: IrElement): IrFunction? {
|
||||
private fun findJdkIntrinsicOrWarn(name: String, warnAgainstElement: IrElement): IrFunction? {
|
||||
val result = jvmIntrinsicsClass?.let { findFunction(it, name) }
|
||||
if(result == null) {
|
||||
logger.errorElement("Couldn't find JVM intrinsic function $name", warnAgainstElement)
|
||||
@@ -1501,7 +1646,7 @@ open class KotlinFileExtractor(
|
||||
result
|
||||
}
|
||||
|
||||
fun isFunction(target: IrFunction, pkgName: String, classNameLogged: String, classNamePredicate: (String) -> Boolean, fName: String, hasQuestionMark: Boolean? = false): Boolean {
|
||||
private fun isFunction(target: IrFunction, pkgName: String, classNameLogged: String, classNamePredicate: (String) -> Boolean, fName: String, hasQuestionMark: Boolean? = false): Boolean {
|
||||
val verbose = false
|
||||
fun verboseln(s: String) { if(verbose) println(s) }
|
||||
verboseln("Attempting match for $pkgName $classNameLogged $fName")
|
||||
@@ -1545,10 +1690,10 @@ open class KotlinFileExtractor(
|
||||
return true
|
||||
}
|
||||
|
||||
fun isFunction(target: IrFunction, pkgName: String, className: String, fName: String, hasQuestionMark: Boolean? = false) =
|
||||
private fun isFunction(target: IrFunction, pkgName: String, className: String, fName: String, hasQuestionMark: Boolean? = false) =
|
||||
isFunction(target, pkgName, className, { it == className }, fName, hasQuestionMark)
|
||||
|
||||
fun isNumericFunction(target: IrFunction, fName: String): Boolean {
|
||||
private fun isNumericFunction(target: IrFunction, fName: String): Boolean {
|
||||
return isFunction(target, "kotlin", "Int", fName) ||
|
||||
isFunction(target, "kotlin", "Byte", fName) ||
|
||||
isFunction(target, "kotlin", "Short", fName) ||
|
||||
@@ -1557,7 +1702,7 @@ open class KotlinFileExtractor(
|
||||
isFunction(target, "kotlin", "Double", fName)
|
||||
}
|
||||
|
||||
fun isArrayType(typeName: String) =
|
||||
private fun isArrayType(typeName: String) =
|
||||
when(typeName) {
|
||||
"Array" -> true
|
||||
"IntArray" -> true
|
||||
@@ -1571,7 +1716,7 @@ open class KotlinFileExtractor(
|
||||
else -> false
|
||||
}
|
||||
|
||||
fun extractCall(c: IrCall, callable: Label<out DbCallable>, stmtExprParent: StmtExprParent) {
|
||||
private fun extractCall(c: IrCall, callable: Label<out DbCallable>, stmtExprParent: StmtExprParent) {
|
||||
with("call", c) {
|
||||
val target = tryReplaceSyntheticFunction(c.symbol.owner)
|
||||
|
||||
@@ -2250,7 +2395,7 @@ open class KotlinFileExtractor(
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun getUpdateInPlaceRHS(origin: IrStatementOrigin?, isExpectedLhs: (IrExpression?) -> Boolean, updateRhs: IrExpression): IrExpression? {
|
||||
private fun getUpdateInPlaceRHS(origin: IrStatementOrigin?, isExpectedLhs: (IrExpression?) -> Boolean, updateRhs: IrExpression): IrExpression? {
|
||||
// Check for a desugared in-place update operator, such as "v += e":
|
||||
return getStatementOriginOperator(origin)?.let {
|
||||
if (updateRhs is IrCall &&
|
||||
@@ -2265,7 +2410,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun writeUpdateInPlaceExpr(origin: IrStatementOrigin, tw: TrapWriter, id: Label<DbAssignexpr>, type: TypeResults, exprParent: ExprParent): Boolean {
|
||||
private fun writeUpdateInPlaceExpr(origin: IrStatementOrigin, tw: TrapWriter, id: Label<DbAssignexpr>, type: TypeResults, exprParent: ExprParent): Boolean {
|
||||
when(origin) {
|
||||
IrStatementOrigin.PLUSEQ -> tw.writeExprs_assignaddexpr(id.cast<DbAssignaddexpr>(), type.javaResult.id, exprParent.parent, exprParent.idx)
|
||||
IrStatementOrigin.MINUSEQ -> tw.writeExprs_assignsubexpr(id.cast<DbAssignsubexpr>(), type.javaResult.id, exprParent.parent, exprParent.idx)
|
||||
@@ -2277,7 +2422,7 @@ open class KotlinFileExtractor(
|
||||
return true
|
||||
}
|
||||
|
||||
fun tryExtractArrayUpdate(e: IrContainerExpression, callable: Label<out DbCallable>, parent: StmtExprParent): Boolean {
|
||||
private fun tryExtractArrayUpdate(e: IrContainerExpression, callable: Label<out DbCallable>, parent: StmtExprParent): Boolean {
|
||||
/*
|
||||
* We're expecting the pattern
|
||||
* {
|
||||
@@ -2348,7 +2493,7 @@ open class KotlinFileExtractor(
|
||||
return false
|
||||
}
|
||||
|
||||
fun extractExpressionStmt(e: IrExpression, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
|
||||
private fun extractExpressionStmt(e: IrExpression, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
|
||||
extractExpression(e, callable, StmtParent(parent, idx))
|
||||
}
|
||||
|
||||
@@ -2356,7 +2501,7 @@ open class KotlinFileExtractor(
|
||||
extractExpression(e, callable, ExprParent(parent, idx, enclosingStmt))
|
||||
}
|
||||
|
||||
fun extractExpression(e: IrExpression, callable: Label<out DbCallable>, parent: StmtExprParent) {
|
||||
private fun extractExpression(e: IrExpression, callable: Label<out DbCallable>, parent: StmtExprParent) {
|
||||
with("expression", e) {
|
||||
when(e) {
|
||||
is IrDelegatingConstructorCall -> {
|
||||
@@ -2599,78 +2744,22 @@ open class KotlinFileExtractor(
|
||||
val exprParent = parent.expr(e, callable)
|
||||
val owner = e.symbol.owner
|
||||
if (owner is IrValueParameter && owner.index == -1 && !owner.isExtensionReceiver()) {
|
||||
val id = tw.getFreshIdLabel<DbThisaccess>()
|
||||
val type = useType(e.type)
|
||||
val locId = tw.getLocation(e)
|
||||
tw.writeExprs_thisaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx)
|
||||
tw.writeExprsKotlinType(id, type.kotlinResult.id)
|
||||
tw.writeHasLocation(id, locId)
|
||||
tw.writeCallableEnclosingExpr(id, callable)
|
||||
tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
|
||||
|
||||
|
||||
fun extractTypeAccess(parent: IrClass){
|
||||
extractTypeAccessRecursive(parent.typeWith(listOf()), locId, id, 0, callable, exprParent.enclosingStmt)
|
||||
}
|
||||
|
||||
when(val ownerParent = owner.parent) {
|
||||
is IrFunction -> {
|
||||
if (ownerParent.dispatchReceiverParameter == owner &&
|
||||
ownerParent.extensionReceiverParameter != null) {
|
||||
|
||||
val ownerParent2 = ownerParent.parent
|
||||
if (ownerParent2 is IrClass){
|
||||
extractTypeAccess(ownerParent2)
|
||||
} else {
|
||||
logger.errorElement("Unhandled qualifier for this", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
is IrClass -> {
|
||||
if (ownerParent.thisReceiver == owner) {
|
||||
extractTypeAccess(ownerParent)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
logger.errorElement("Unexpected owner parent for this access: " + ownerParent.javaClass, e)
|
||||
}
|
||||
}
|
||||
extractThisAccess(e, exprParent, callable)
|
||||
} else {
|
||||
val id = tw.getFreshIdLabel<DbVaraccess>()
|
||||
val type = useType(e.type)
|
||||
val locId = tw.getLocation(e)
|
||||
tw.writeExprs_varaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx)
|
||||
tw.writeExprsKotlinType(id, type.kotlinResult.id)
|
||||
tw.writeHasLocation(id, locId)
|
||||
tw.writeCallableEnclosingExpr(id, callable)
|
||||
tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
|
||||
|
||||
val vId = useValueDeclaration(owner)
|
||||
if (vId != null) {
|
||||
tw.writeVariableBinding(id, vId)
|
||||
}
|
||||
extractVariableAccess(useValueDeclaration(owner), e.type, tw.getLocation(e), exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt)
|
||||
}
|
||||
}
|
||||
is IrGetField -> {
|
||||
val exprParent = parent.expr(e, callable)
|
||||
val id = tw.getFreshIdLabel<DbVaraccess>()
|
||||
val type = useType(e.type)
|
||||
val locId = tw.getLocation(e)
|
||||
tw.writeExprs_varaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx)
|
||||
tw.writeExprsKotlinType(id, type.kotlinResult.id)
|
||||
tw.writeHasLocation(id, locId)
|
||||
tw.writeCallableEnclosingExpr(id, callable)
|
||||
tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
|
||||
val owner = tryReplaceAndroidSyntheticField(e.symbol.owner)
|
||||
val vId = useField(owner)
|
||||
tw.writeVariableBinding(id, vId)
|
||||
tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
|
||||
|
||||
val receiver = e.receiver
|
||||
if (receiver != null) {
|
||||
extractExpressionExpr(receiver, callable, id, -1, exprParent.enclosingStmt)
|
||||
} else if (owner.isStatic) {
|
||||
extractStaticTypeAccessQualifier(owner, id, locId, callable, exprParent.enclosingStmt)
|
||||
val locId = tw.getLocation(e)
|
||||
extractVariableAccess(useField(owner), e.type, locId, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt).also { id ->
|
||||
val receiver = e.receiver
|
||||
if (receiver != null) {
|
||||
extractExpressionExpr(receiver, callable, id, -1, exprParent.enclosingStmt)
|
||||
} else if (owner.isStatic) {
|
||||
extractStaticTypeAccessQualifier(owner, id, locId, callable, exprParent.enclosingStmt)
|
||||
}
|
||||
}
|
||||
}
|
||||
is IrGetEnumValue -> {
|
||||
@@ -2971,6 +3060,71 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractThisAccess(e: IrGetValue, exprParent: ExprParent, callable: Label<out DbCallable>) {
|
||||
val containingDeclaration = declarationStack.peek()
|
||||
val locId = tw.getLocation(e)
|
||||
val type = useType(e.type)
|
||||
|
||||
if (containingDeclaration.shouldExtractAsStatic && containingDeclaration.parentClassOrNull?.isNonCompanionObject == true) {
|
||||
// Use of `this` in a non-companion object member that will be lowered to a static function -- replace with a reference
|
||||
// to the corresponding static object instance.
|
||||
val instanceField = useObjectClassInstance(containingDeclaration.parentAsClass)
|
||||
extractVariableAccess(instanceField.id, e.type, locId, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt).also { varAccessId ->
|
||||
extractStaticTypeAccessQualifier(containingDeclaration, varAccessId, locId, callable, exprParent.enclosingStmt)
|
||||
}
|
||||
} else {
|
||||
val id = tw.getFreshIdLabel<DbThisaccess>()
|
||||
|
||||
tw.writeExprs_thisaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx)
|
||||
tw.writeExprsKotlinType(id, type.kotlinResult.id)
|
||||
tw.writeHasLocation(id, locId)
|
||||
tw.writeCallableEnclosingExpr(id, callable)
|
||||
tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
|
||||
|
||||
fun extractTypeAccess(parent: IrClass) {
|
||||
extractTypeAccessRecursive(parent.typeWith(listOf()), locId, id, 0, callable, exprParent.enclosingStmt)
|
||||
}
|
||||
|
||||
val owner = e.symbol.owner
|
||||
when(val ownerParent = owner.parent) {
|
||||
is IrFunction -> {
|
||||
if (ownerParent.dispatchReceiverParameter == owner &&
|
||||
ownerParent.extensionReceiverParameter != null) {
|
||||
|
||||
val ownerParent2 = ownerParent.parent
|
||||
if (ownerParent2 is IrClass){
|
||||
extractTypeAccess(ownerParent2)
|
||||
} else {
|
||||
logger.errorElement("Unhandled qualifier for this", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
is IrClass -> {
|
||||
if (ownerParent.thisReceiver == owner) {
|
||||
extractTypeAccess(ownerParent)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
logger.errorElement("Unexpected owner parent for this access: " + ownerParent.javaClass, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractVariableAccess(variable: Label<out DbVariable>?, irType: IrType, locId: Label<out DbLocation>, parent: Label<out DbExprparent>, idx: Int, callable: Label<out DbCallable>, enclosingStmt: Label<out DbStmt>) =
|
||||
tw.getFreshIdLabel<DbVaraccess>().also {
|
||||
val type = useType(irType)
|
||||
tw.writeExprs_varaccess(it, type.javaResult.id, parent, idx)
|
||||
tw.writeExprsKotlinType(it, type.kotlinResult.id)
|
||||
tw.writeHasLocation(it, locId)
|
||||
tw.writeCallableEnclosingExpr(it, callable)
|
||||
tw.writeStatementEnclosingExpr(it, enclosingStmt)
|
||||
|
||||
if (variable != null) {
|
||||
tw.writeVariableBinding(it, variable)
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractLoop(
|
||||
loop: IrLoop,
|
||||
stmtExprParent: StmtExprParent,
|
||||
@@ -3819,7 +3973,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractVarargElement(e: IrVarargElement, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
|
||||
private fun extractVarargElement(e: IrVarargElement, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
|
||||
with("vararg element", e) {
|
||||
val argExpr = when(e) {
|
||||
is IrExpression -> e
|
||||
@@ -4011,7 +4165,7 @@ open class KotlinFileExtractor(
|
||||
return initId
|
||||
}
|
||||
|
||||
fun extractTypeOperatorCall(e: IrTypeOperatorCall, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
|
||||
private fun extractTypeOperatorCall(e: IrTypeOperatorCall, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
|
||||
with("type operator call", e) {
|
||||
when(e.operator) {
|
||||
IrTypeOperator.CAST -> {
|
||||
@@ -4383,6 +4537,9 @@ open class KotlinFileExtractor(
|
||||
GENERATED_DATA_CLASS_MEMBER(2),
|
||||
DEFAULT_PROPERTY_ACCESSOR(3),
|
||||
CLASS_INITIALISATION_METHOD(4),
|
||||
ENUM_CLASS_SPECIAL_MEMBER(5)
|
||||
ENUM_CLASS_SPECIAL_MEMBER(5),
|
||||
DELEGATED_PROPERTY_GETTER(6),
|
||||
DELEGATED_PROPERTY_SETTER(7),
|
||||
JVMSTATIC_PROXY_METHOD(8),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.lower.parents
|
||||
import org.jetbrains.kotlin.backend.common.lower.parentsWithSelf
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.propertyIfAccessor
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -23,8 +24,10 @@ import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.load.kotlin.getJvmModuleNameForDeserializedDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.NameUtils
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
@@ -49,7 +52,7 @@ open class KotlinUsesExtractor(
|
||||
javaLangObject?.typeWith()
|
||||
}
|
||||
|
||||
fun usePackage(pkg: String): Label<out DbPackage> {
|
||||
private fun usePackage(pkg: String): Label<out DbPackage> {
|
||||
return extractPackage(pkg)
|
||||
}
|
||||
|
||||
@@ -108,14 +111,26 @@ open class KotlinUsesExtractor(
|
||||
}
|
||||
data class TypeResults(val javaResult: TypeResult<DbType>, val kotlinResult: TypeResult<DbKt_type>)
|
||||
|
||||
fun useType(t: IrType, context: TypeContext = TypeContext.OTHER) =
|
||||
fun useType(t: IrType, context: TypeContext = TypeContext.OTHER): TypeResults {
|
||||
when(t) {
|
||||
is IrSimpleType -> useSimpleType(t, context)
|
||||
is IrSimpleType -> return useSimpleType(t, context)
|
||||
else -> {
|
||||
logger.error("Unrecognised IrType: " + t.javaClass)
|
||||
TypeResults(TypeResult(fakeLabel(), "unknown", "unknown"), TypeResult(fakeLabel(), "unknown", "unknown"))
|
||||
return extractErrorType()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractErrorType(): TypeResults {
|
||||
val typeId = tw.getLabelFor<DbErrortype>("@\"errorType\"") {
|
||||
tw.writeError_type(it)
|
||||
}
|
||||
val kotlinTypeId = tw.getLabelFor<DbKt_nullable_type>("@\"errorKotlinType\"") {
|
||||
tw.writeKt_nullable_types(it, typeId)
|
||||
}
|
||||
return TypeResults(TypeResult(typeId, null, "<CodeQL error type>"),
|
||||
TypeResult(kotlinTypeId, null, "<CodeQL error type>"))
|
||||
}
|
||||
|
||||
fun getJavaEquivalentClass(c: IrClass) =
|
||||
getJavaEquivalentClassId(c)?.let { pluginContext.referenceClass(it.asSingleFqName()) }?.owner
|
||||
@@ -154,12 +169,12 @@ open class KotlinUsesExtractor(
|
||||
} ?: argsIncludingOuterClasses
|
||||
}
|
||||
|
||||
fun isStaticClass(c: IrClass) = c.visibility != DescriptorVisibilities.LOCAL && !c.isInner
|
||||
private fun isStaticClass(c: IrClass) = c.visibility != DescriptorVisibilities.LOCAL && !c.isInner
|
||||
|
||||
// Gets nested inner classes starting at `c` and proceeding outwards to the innermost enclosing static class.
|
||||
// For example, for (java syntax) `class A { static class B { class C { class D { } } } }`,
|
||||
// `nonStaticParentsWithSelf(D)` = `[D, C, B]`.
|
||||
fun parentsWithTypeParametersInScope(c: IrClass): List<IrDeclarationParent> {
|
||||
private fun parentsWithTypeParametersInScope(c: IrClass): List<IrDeclarationParent> {
|
||||
val parentsList = c.parentsWithSelf.toList()
|
||||
val firstOuterClassIdx = parentsList.indexOfFirst { it is IrClass && isStaticClass(it) }
|
||||
return if (firstOuterClassIdx == -1) parentsList else parentsList.subList(0, firstOuterClassIdx + 1)
|
||||
@@ -168,14 +183,14 @@ open class KotlinUsesExtractor(
|
||||
// Gets the type parameter symbols that are in scope for class `c` in Kotlin order (i.e. for
|
||||
// `class NotInScope<T> { static class OutermostInScope<A, B> { class QueryClass<C, D> { } } }`,
|
||||
// `getTypeParametersInScope(QueryClass)` = `[C, D, A, B]`.
|
||||
fun getTypeParametersInScope(c: IrClass) =
|
||||
private fun getTypeParametersInScope(c: IrClass) =
|
||||
parentsWithTypeParametersInScope(c).mapNotNull({ getTypeParameters(it) }).flatten()
|
||||
|
||||
// Returns a map from `c`'s type variables in scope to type arguments `argsIncludingOuterClasses`.
|
||||
// Hack for the time being: the substituted types are always nullable, to prevent downstream code
|
||||
// from replacing a generic parameter by a primitive. As and when we extract Kotlin types we will
|
||||
// need to track this information in more detail.
|
||||
fun makeTypeGenericSubstitutionMap(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>) =
|
||||
private fun makeTypeGenericSubstitutionMap(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>) =
|
||||
getTypeParametersInScope(c).map({ it.symbol }).zip(argsIncludingOuterClasses.map { it.withQuestionMark(true) }).toMap()
|
||||
|
||||
fun makeGenericSubstitutionFunction(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>) =
|
||||
@@ -239,13 +254,13 @@ open class KotlinUsesExtractor(
|
||||
|
||||
private fun isArray(t: IrSimpleType) = t.isBoxedArray || t.isPrimitiveArray()
|
||||
|
||||
fun extractClassLaterIfExternal(c: IrClass) {
|
||||
private fun extractClassLaterIfExternal(c: IrClass) {
|
||||
if (isExternalDeclaration(c)) {
|
||||
extractExternalClassLater(c)
|
||||
}
|
||||
}
|
||||
|
||||
fun extractExternalEnclosingClassLater(d: IrDeclaration) {
|
||||
private fun extractExternalEnclosingClassLater(d: IrDeclaration) {
|
||||
when (val parent = d.parent) {
|
||||
is IrClass -> extractExternalClassLater(parent)
|
||||
is IrFunction -> extractExternalEnclosingClassLater(parent)
|
||||
@@ -254,7 +269,7 @@ open class KotlinUsesExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractPropertyLaterIfExternalFileMember(p: IrProperty) {
|
||||
private fun extractPropertyLaterIfExternalFileMember(p: IrProperty) {
|
||||
if (isExternalFileClassMember(p)) {
|
||||
extractExternalClassLater(p.parentAsClass)
|
||||
dependencyCollector?.addDependency(p, externalClassExtractor.propertySignature)
|
||||
@@ -262,7 +277,7 @@ open class KotlinUsesExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractFieldLaterIfExternalFileMember(f: IrField) {
|
||||
private fun extractFieldLaterIfExternalFileMember(f: IrField) {
|
||||
if (isExternalFileClassMember(f)) {
|
||||
extractExternalClassLater(f.parentAsClass)
|
||||
dependencyCollector?.addDependency(f, externalClassExtractor.fieldSignature)
|
||||
@@ -270,7 +285,7 @@ open class KotlinUsesExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractFunctionLaterIfExternalFileMember(f: IrFunction) {
|
||||
private fun extractFunctionLaterIfExternalFileMember(f: IrFunction) {
|
||||
if (isExternalFileClassMember(f)) {
|
||||
extractExternalClassLater(f.parentAsClass)
|
||||
(f as? IrSimpleFunction)?.correspondingPropertySymbol?.let {
|
||||
@@ -301,7 +316,7 @@ open class KotlinUsesExtractor(
|
||||
externalClassExtractor.extractLater(c)
|
||||
}
|
||||
|
||||
fun tryReplaceAndroidSyntheticClass(c: IrClass): IrClass {
|
||||
private fun tryReplaceAndroidSyntheticClass(c: IrClass): IrClass {
|
||||
// The Android Kotlin Extensions Gradle plugin introduces synthetic functions, fields and classes. The most
|
||||
// obvious signature is that they lack any supertype information even though they are not root classes.
|
||||
// If possible, replace them by a real version of the same class.
|
||||
@@ -503,7 +518,7 @@ open class KotlinUsesExtractor(
|
||||
// but returns boxed arrays with a nullable, invariant component type, with any nested arrays
|
||||
// similarly transformed. For example, Array<out Array<in E>> would become Array<Array<E?>?>
|
||||
// Array<*> will become Array<Any?>.
|
||||
fun getInvariantNullableArrayType(arrayType: IrSimpleType): IrSimpleType =
|
||||
private fun getInvariantNullableArrayType(arrayType: IrSimpleType): IrSimpleType =
|
||||
if (arrayType.isPrimitiveArray())
|
||||
arrayType
|
||||
else {
|
||||
@@ -528,7 +543,7 @@ open class KotlinUsesExtractor(
|
||||
)
|
||||
}
|
||||
|
||||
fun useArrayType(arrayType: IrSimpleType, componentType: IrType, elementType: IrType, dimensions: Int, isPrimitiveArray: Boolean): TypeResults {
|
||||
private fun useArrayType(arrayType: IrSimpleType, componentType: IrType, elementType: IrType, dimensions: Int, isPrimitiveArray: Boolean): TypeResults {
|
||||
|
||||
// Ensure we extract Array<Int> as Integer[], not int[], for example:
|
||||
fun nullableIfNotPrimitive(type: IrType) = if (type.isPrimitiveType() && !isPrimitiveArray) type.makeNullable() else type
|
||||
@@ -579,7 +594,7 @@ open class KotlinUsesExtractor(
|
||||
RETURN, GENERIC_ARGUMENT, OTHER
|
||||
}
|
||||
|
||||
fun useSimpleType(s: IrSimpleType, context: TypeContext): TypeResults {
|
||||
private fun useSimpleType(s: IrSimpleType, context: TypeContext): TypeResults {
|
||||
if (s.abbreviation != null) {
|
||||
// TODO: Extract this information
|
||||
}
|
||||
@@ -754,11 +769,25 @@ open class KotlinUsesExtractor(
|
||||
|
||||
data class FunctionNames(val nameInDB: String, val kotlinName: String)
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
private fun getJvmModuleName(f: IrFunction) =
|
||||
NameUtils.sanitizeAsJavaIdentifier(
|
||||
getJvmModuleNameForDeserializedDescriptor(f.descriptor) ?: JvmCodegenUtil.getModuleName(pluginContext.moduleDescriptor)
|
||||
)
|
||||
|
||||
fun getFunctionShortName(f: IrFunction) : FunctionNames {
|
||||
if (f.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA || f.isAnonymousFunction)
|
||||
return FunctionNames(
|
||||
OperatorNameConventions.INVOKE.asString(),
|
||||
OperatorNameConventions.INVOKE.asString())
|
||||
|
||||
fun getSuffixIfInternal() =
|
||||
if (f.visibility == DescriptorVisibilities.INTERNAL) {
|
||||
"\$" + getJvmModuleName(f)
|
||||
} else {
|
||||
""
|
||||
}
|
||||
|
||||
(f as? IrSimpleFunction)?.correspondingPropertySymbol?.let {
|
||||
val propName = it.owner.name.asString()
|
||||
val getter = it.owner.getter
|
||||
@@ -774,35 +803,26 @@ open class KotlinUsesExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
when (f) {
|
||||
getter -> {
|
||||
val defaultFunctionName = JvmAbi.getterName(propName)
|
||||
val defaultDbName = if (getter.visibility == DescriptorVisibilities.PRIVATE && getter.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) {
|
||||
// In JVM these functions don't exist, instead the backing field is accessed directly
|
||||
defaultFunctionName + "\$private"
|
||||
} else {
|
||||
defaultFunctionName
|
||||
}
|
||||
return FunctionNames(getJvmName(getter) ?: defaultDbName, defaultFunctionName)
|
||||
}
|
||||
setter -> {
|
||||
val defaultFunctionName = JvmAbi.setterName(propName)
|
||||
val defaultDbName = if (setter.visibility == DescriptorVisibilities.PRIVATE && setter.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) {
|
||||
// In JVM these functions don't exist, instead the backing field is accessed directly
|
||||
defaultFunctionName + "\$private"
|
||||
} else {
|
||||
defaultFunctionName
|
||||
}
|
||||
return FunctionNames(getJvmName(setter) ?: defaultDbName, defaultFunctionName)
|
||||
}
|
||||
val maybeFunctionName = when (f) {
|
||||
getter -> JvmAbi.getterName(propName)
|
||||
setter -> JvmAbi.setterName(propName)
|
||||
else -> {
|
||||
logger.error(
|
||||
"Function has a corresponding property, but is neither the getter nor the setter"
|
||||
)
|
||||
null
|
||||
}
|
||||
}
|
||||
maybeFunctionName?.let { defaultFunctionName ->
|
||||
val suffix = if (f.visibility == DescriptorVisibilities.PRIVATE && f.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) {
|
||||
"\$private"
|
||||
} else {
|
||||
getSuffixIfInternal()
|
||||
}
|
||||
return FunctionNames(getJvmName(f) ?: "$defaultFunctionName$suffix", defaultFunctionName)
|
||||
}
|
||||
}
|
||||
return FunctionNames(getJvmName(f) ?: f.name.asString(), f.name.asString())
|
||||
return FunctionNames(getJvmName(f) ?: "${f.name.asString()}${getSuffixIfInternal()}", f.name.asString())
|
||||
}
|
||||
|
||||
// This excludes class type parameters that show up in (at least) constructors' typeParameters list.
|
||||
@@ -810,14 +830,14 @@ open class KotlinUsesExtractor(
|
||||
return if (f is IrConstructor) f.typeParameters else f.typeParameters.filter { it.parent == f }
|
||||
}
|
||||
|
||||
fun getTypeParameters(dp: IrDeclarationParent): List<IrTypeParameter> =
|
||||
private fun getTypeParameters(dp: IrDeclarationParent): List<IrTypeParameter> =
|
||||
when(dp) {
|
||||
is IrClass -> dp.typeParameters
|
||||
is IrFunction -> getFunctionTypeParameters(dp)
|
||||
else -> listOf()
|
||||
}
|
||||
|
||||
fun getEnclosingClass(it: IrDeclarationParent): IrClass? =
|
||||
private fun getEnclosingClass(it: IrDeclarationParent): IrClass? =
|
||||
when(it) {
|
||||
is IrClass -> it
|
||||
is IrFunction -> getEnclosingClass(it.parent)
|
||||
@@ -924,7 +944,7 @@ open class KotlinUsesExtractor(
|
||||
null
|
||||
} ?: t
|
||||
|
||||
fun getJavaTypeArgument(jt: JavaType, idx: Int) =
|
||||
private fun getJavaTypeArgument(jt: JavaType, idx: Int) =
|
||||
when(jt) {
|
||||
is JavaClassifierType -> jt.typeArguments.getOrNull(idx)
|
||||
is JavaArrayType -> if (idx == 0) jt.componentType else null
|
||||
@@ -1153,7 +1173,7 @@ open class KotlinUsesExtractor(
|
||||
"kotlin.Boolean", "kotlin.Byte", "kotlin.Char", "kotlin.Double", "kotlin.Float", "kotlin.Int", "kotlin.Long", "kotlin.Number", "kotlin.Short"
|
||||
)
|
||||
|
||||
fun kotlinFunctionToJavaEquivalent(f: IrFunction, noReplace: Boolean) =
|
||||
private fun kotlinFunctionToJavaEquivalent(f: IrFunction, noReplace: Boolean) =
|
||||
if (noReplace)
|
||||
f
|
||||
else
|
||||
@@ -1346,14 +1366,14 @@ open class KotlinUsesExtractor(
|
||||
return "@\"typevar;{$parentLabel};${param.name}\""
|
||||
}
|
||||
|
||||
fun useTypeParameter(param: IrTypeParameter) =
|
||||
private fun useTypeParameter(param: IrTypeParameter) =
|
||||
TypeResult(
|
||||
tw.getLabelFor<DbTypevariable>(getTypeParameterLabel(param)),
|
||||
useType(eraseTypeParameter(param)).javaResult.signature,
|
||||
param.name.asString()
|
||||
)
|
||||
|
||||
fun extractModifier(m: String): Label<DbModifier> {
|
||||
private fun extractModifier(m: String): Label<DbModifier> {
|
||||
val modifierLabel = "@\"modifier;$m\""
|
||||
val id: Label<DbModifier> = tw.getLabelFor(modifierLabel, {
|
||||
tw.writeModifiers(it, m)
|
||||
@@ -1435,7 +1455,7 @@ open class KotlinUsesExtractor(
|
||||
* Note that `Array<T>` is retained (with `T` itself erased) because these are expected to be lowered to Java
|
||||
* arrays, which are not generic.
|
||||
*/
|
||||
fun erase (t: IrType): IrType {
|
||||
private fun erase (t: IrType): IrType {
|
||||
if (t is IrSimpleType) {
|
||||
val classifier = t.classifier
|
||||
val owner = classifier.owner
|
||||
@@ -1488,7 +1508,7 @@ open class KotlinUsesExtractor(
|
||||
fun useValueParameter(vp: IrValueParameter, parent: Label<out DbCallable>?): Label<out DbParam> =
|
||||
tw.getLabelFor(getValueParameterLabel(vp, parent))
|
||||
|
||||
fun isDirectlyExposedCompanionObjectField(f: IrField) =
|
||||
private fun isDirectlyExposedCompanionObjectField(f: IrField) =
|
||||
f.hasAnnotation(FqName("kotlin.jvm.JvmField")) ||
|
||||
f.correspondingPropertySymbol?.owner?.let {
|
||||
it.isConst || it.isLateinit
|
||||
@@ -1514,7 +1534,7 @@ open class KotlinUsesExtractor(
|
||||
// otherwise two extension properties declared in the same enclosing context will get
|
||||
// clashing trap labels. These are always private, so we can just make up a label without
|
||||
// worrying about their names as seen from Java.
|
||||
val extensionPropertyDiscriminator = getExtensionReceiverType(f)?.let { "extension;${useType(it)}" } ?: ""
|
||||
val extensionPropertyDiscriminator = getExtensionReceiverType(f)?.let { "extension;${useType(it).javaResult.id}" } ?: ""
|
||||
return "@\"field;{$parentId};${extensionPropertyDiscriminator}${f.name.asString()}\""
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
class CommentExtractor(private val fileExtractor: KotlinFileExtractor, private val file: IrFile, private val fileLabel: Label<out DbFile>) {
|
||||
private val tw = fileExtractor.tw
|
||||
private val logger = fileExtractor.logger
|
||||
private val ktFile = Psi2Ir().getKtFile(file)
|
||||
private val psi2Ir = Psi2Ir(logger)
|
||||
private val ktFile = psi2Ir.getKtFile(file)
|
||||
|
||||
fun extract() {
|
||||
if (ktFile == null) {
|
||||
@@ -85,7 +86,7 @@ class CommentExtractor(private val fileExtractor: KotlinFileExtractor, private v
|
||||
val ownerPsi = getKDocOwner(comment) ?: return
|
||||
|
||||
val owners = mutableListOf<IrElement>()
|
||||
file.accept(IrVisitorLookup(ownerPsi, file), owners)
|
||||
file.accept(IrVisitorLookup(psi2Ir, ownerPsi, file), owners)
|
||||
|
||||
for (ownerIr in owners) {
|
||||
val ownerLabel =
|
||||
|
||||
@@ -68,7 +68,7 @@ fun getIrClassVirtualFile(irClass: IrClass): VirtualFile? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun getRawIrClassBinaryPath(irClass: IrClass) =
|
||||
private fun getRawIrClassBinaryPath(irClass: IrClass) =
|
||||
getIrClassVirtualFile(irClass)?.let {
|
||||
val path = it.path
|
||||
if(it.fileSystem.protocol == StandardFileSystems.JRT_PROTOCOL)
|
||||
@@ -92,4 +92,4 @@ fun getContainingClassOrSelf(decl: IrDeclaration): IrClass? {
|
||||
}
|
||||
|
||||
fun getJavaEquivalentClassId(c: IrClass) =
|
||||
c.fqNameWhenAvailable?.toUnsafe()?.let { JavaToKotlinClassMap.mapKotlinToJava(it) }
|
||||
c.fqNameWhenAvailable?.toUnsafe()?.let { JavaToKotlinClassMap.mapKotlinToJava(it) }
|
||||
|
||||
@@ -8,7 +8,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.util.isFakeOverride
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
class IrVisitorLookup(private val psi: PsiElement, private val file: IrFile) :
|
||||
class IrVisitorLookup(private val psi2Ir: Psi2Ir, private val psi: PsiElement, private val file: IrFile) :
|
||||
IrElementVisitor<Unit, MutableCollection<IrElement>> {
|
||||
private val location = psi.getLocation()
|
||||
|
||||
@@ -27,7 +27,7 @@ class IrVisitorLookup(private val psi: PsiElement, private val file: IrFile) :
|
||||
}
|
||||
|
||||
if (location.contains(elementLocation)) {
|
||||
val psiElement = Psi2Ir().findPsiElement(element, file)
|
||||
val psiElement = psi2Ir.findPsiElement(element, file)
|
||||
if (psiElement == psi) {
|
||||
// There can be multiple IrElements that match the same PSI element.
|
||||
data.add(element)
|
||||
@@ -35,4 +35,4 @@ class IrVisitorLookup(private val psi: PsiElement, private val file: IrFile) :
|
||||
}
|
||||
element.acceptChildren(this, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ private val specialFunctions = mapOf(
|
||||
|
||||
private val specialFunctionShortNames = specialFunctions.keys.map { it.functionName }.toSet()
|
||||
|
||||
fun getSpecialJvmName(f: IrFunction): String? {
|
||||
private fun getSpecialJvmName(f: IrFunction): String? {
|
||||
if (specialFunctionShortNames.contains(f.name) && f is IrSimpleFunction) {
|
||||
f.allOverridden(true).forEach { overriddenFunc ->
|
||||
overriddenFunc.parentClassOrNull?.fqNameWhenAvailable?.let { parentFqName ->
|
||||
@@ -87,4 +87,4 @@ fun getJvmName(container: IrAnnotationContainer): String? {
|
||||
}
|
||||
}
|
||||
return (container as? IrFunction)?.let { getSpecialJvmName(container) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ fun IrType.substituteTypeArguments(params: List<IrTypeParameter>, arguments: Lis
|
||||
else -> this
|
||||
}
|
||||
|
||||
fun IrSimpleType.substituteTypeArguments(substitutionMap: Map<IrTypeParameterSymbol, IrTypeArgument>): IrSimpleType {
|
||||
private fun IrSimpleType.substituteTypeArguments(substitutionMap: Map<IrTypeParameterSymbol, IrTypeArgument>): IrSimpleType {
|
||||
if (substitutionMap.isEmpty()) return this
|
||||
|
||||
val newArguments = arguments.map {
|
||||
@@ -100,7 +100,7 @@ private fun subProjectedType(substitutionMap: Map<IrTypeParameterSymbol, IrTypeA
|
||||
}
|
||||
} ?: makeTypeProjection(t.substituteTypeArguments(substitutionMap), outerVariance)
|
||||
|
||||
fun IrTypeArgument.upperBound(context: IrPluginContext) =
|
||||
private fun IrTypeArgument.upperBound(context: IrPluginContext) =
|
||||
when(this) {
|
||||
is IrStarProjection -> context.irBuiltIns.anyNType
|
||||
is IrTypeProjection -> when(this.variance) {
|
||||
@@ -111,7 +111,7 @@ fun IrTypeArgument.upperBound(context: IrPluginContext) =
|
||||
else -> context.irBuiltIns.anyNType
|
||||
}
|
||||
|
||||
fun IrTypeArgument.lowerBound(context: IrPluginContext) =
|
||||
private fun IrTypeArgument.lowerBound(context: IrPluginContext) =
|
||||
when(this) {
|
||||
is IrStarProjection -> context.irBuiltIns.nothingType
|
||||
is IrTypeProjection -> when(this.variance) {
|
||||
@@ -200,7 +200,7 @@ fun IrTypeArgument.withQuestionMark(b: Boolean): IrTypeArgument =
|
||||
|
||||
typealias TypeSubstitution = (IrType, KotlinUsesExtractor.TypeContext, IrPluginContext) -> IrType
|
||||
|
||||
fun matchingTypeParameters(l: IrTypeParameter?, r: IrTypeParameter): Boolean {
|
||||
private fun matchingTypeParameters(l: IrTypeParameter?, r: IrTypeParameter): Boolean {
|
||||
if (l === r)
|
||||
return true
|
||||
if (l == null)
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.github.codeql.FileLogger
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
|
||||
class Psi2Ir : Psi2IrFacade {
|
||||
companion object {
|
||||
val psiManager = PsiSourceManager()
|
||||
}
|
||||
|
||||
class Psi2Ir(private val logger: FileLogger) : Psi2IrFacade {
|
||||
override fun getKtFile(irFile: IrFile): KtFile? {
|
||||
return psiManager.getKtFile(irFile)
|
||||
logger.warn("Comment extraction is not supported for Kotlin < 1.5.20")
|
||||
return null
|
||||
}
|
||||
|
||||
override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
return psiManager.findPsiElement(irElement, irFile)
|
||||
logger.error("Attempted comment extraction for Kotlin < 1.5.20")
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.github.codeql.FileLogger
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
|
||||
class Psi2Ir : Psi2IrFacade {
|
||||
companion object {
|
||||
val psiManager = PsiSourceManager()
|
||||
}
|
||||
|
||||
class Psi2Ir(private val logger: FileLogger) : Psi2IrFacade {
|
||||
override fun getKtFile(irFile: IrFile): KtFile? {
|
||||
return psiManager.getKtFile(irFile)
|
||||
logger.warn("Comment extraction is not supported for Kotlin < 1.5.20")
|
||||
return null
|
||||
}
|
||||
|
||||
override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
return psiManager.findPsiElement(irElement, irFile)
|
||||
logger.error("Attempted comment extraction for Kotlin < 1.5.20")
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.github.codeql.FileLogger
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
|
||||
class Psi2Ir : Psi2IrFacade {
|
||||
companion object {
|
||||
val psiManager = PsiSourceManager()
|
||||
}
|
||||
|
||||
class Psi2Ir(private val logger: FileLogger) : Psi2IrFacade {
|
||||
override fun getKtFile(irFile: IrFile): KtFile? {
|
||||
return psiManager.getKtFile(irFile)
|
||||
logger.warn("Comment extraction is not supported for Kotlin < 1.5.20")
|
||||
return null
|
||||
}
|
||||
|
||||
override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
return psiManager.findPsiElement(irElement, irFile)
|
||||
logger.error("Attempted comment extraction for Kotlin < 1.5.20")
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.github.codeql.FileLogger
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
|
||||
@@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
class Psi2Ir: Psi2IrFacade {
|
||||
class Psi2Ir(private val logger: FileLogger): Psi2IrFacade {
|
||||
override fun getKtFile(irFile: IrFile): KtFile? {
|
||||
return irFile.getKtFile()
|
||||
}
|
||||
@@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade {
|
||||
override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
return PsiSourceManager.findPsiElement(irElement, irFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user