Merge branch 'main' into js/case-sensitive-middleware

This commit is contained in:
Asger F
2022-07-14 09:38:35 +02:00
committed by GitHub
748 changed files with 15085 additions and 4847 deletions

View File

@@ -10,6 +10,7 @@ on:
- "*/ql/lib/**/*.qll"
- "!**/experimental/**"
- "!ql/**"
- "!swift/**"
- ".github/workflows/check-change-note.yml"
jobs:

View File

@@ -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

View File

@@ -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 }}

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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",

View File

@@ -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

View File

@@ -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.

View File

@@ -1,4 +0,0 @@
---
category: fix
---
* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`.

View File

@@ -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.

View 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`.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.2.3
lastReleaseVersion: 0.3.0

View File

@@ -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

View File

@@ -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()
)
}
/**

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)) }

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -1,3 +1,5 @@
## 0.2.0
## 0.1.4
## 0.1.3

View File

@@ -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)

View File

@@ -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%"])
}

View File

@@ -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())

View File

@@ -15,6 +15,7 @@ class VariableAccessInInitializer extends VariableAccess {
Variable var;
Initializer init;
pragma[nomagic]
VariableAccessInInitializer() {
init.getDeclaration() = var and
init.getExpr().getAChild*() = this

View File

@@ -0,0 +1,4 @@
---
category: breaking
---
* Contextual queries and the query libraries they depend on have been moved to the `codeql/cpp-all` package.

View File

@@ -0,0 +1 @@
## 0.2.0

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.1.4
lastReleaseVersion: 0.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 0.2.0-dev
version: 0.2.1-dev
groups:
- cpp
- queries

View File

@@ -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 |

View File

@@ -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

View 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) {}
}

View File

@@ -1,3 +1,5 @@
## 1.2.0
## 1.1.4
## 1.1.3

View File

@@ -0,0 +1 @@
## 1.2.0

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.1.4
lastReleaseVersion: 1.2.0

View File

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

View File

@@ -1,3 +1,5 @@
## 1.2.0
## 1.1.4
## 1.1.3

View File

@@ -0,0 +1 @@
## 1.2.0

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.1.4
lastReleaseVersion: 1.2.0

View File

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

View File

@@ -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

View File

@@ -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.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.2.3
lastReleaseVersion: 0.3.0

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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.

View File

@@ -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`).

View File

@@ -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`.

View File

@@ -0,0 +1,4 @@
---
category: breaking
---
* Contextual queries and the query libraries they depend on have been moved to the `codeql/csharp-all` package.

View 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.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.1.4
lastReleaseVersion: 0.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-queries
version: 0.2.0-dev
version: 0.2.1-dev
groups:
- csharp
- queries

View File

@@ -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>`__

View File

@@ -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>`."

View File

@@ -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>

View File

@@ -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.

View File

@@ -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

View File

@@ -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.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.1.4
lastReleaseVersion: 0.2.0

View File

@@ -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

View File

@@ -1,3 +1,5 @@
## 0.2.0
## 0.1.4
## 0.1.3

View File

@@ -0,0 +1 @@
## 0.2.0

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.1.4
lastReleaseVersion: 0.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/go-queries
version: 0.2.0-dev
version: 0.2.1-dev
groups:
- go
- queries

View File

@@ -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,,,,,,,,,,,,,,,,,,,,,
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
2 android.app 16 103 7 9 18 85
3 android.content 24 27 31 108 16 8 4 27 31 77
4 android.database 59 30 59 30
5 android.net 60 45 15
6 android.os 2 122 2 41 81
7 android.util 6 16 6 16
8 android.webkit 3 2 3 2
9 android.widget 1 1 1 1
10 androidx.slice 2 5 88 2 5 27 61
11 cn.hutool.core.codec 1 1
12 com.esotericsoftware.kryo.io 1 1
13 com.esotericsoftware.kryo5.io 1 1
14 com.fasterxml.jackson.core 1 1
15 com.fasterxml.jackson.databind 6 6
16 com.google.common.base 4 85 3 1 62 23
17 com.google.common.cache 17 17
18 com.google.common.collect 553 2 551
19 com.google.common.flogger 29 29
20 com.google.common.io 6 73 6 72 1
21 com.opensymphony.xwork2.ognl 3 3
22 com.rabbitmq.client 21 7 21 7
23 com.unboundid.ldap.sdk 17 17
24 com.zaxxer.hikari 2 2
25 flexjson 1 1
26 groovy.lang 26 26
27 groovy.util 5 5
28 jakarta.faces.context 2 7 2 7
29 jakarta.json 123 100 23
30 jakarta.ws.rs.client 1 1
31 jakarta.ws.rs.container 9 9
32 jakarta.ws.rs.core 2 149 2 94 55
33 java.beans 1 1
34 java.io 37 39 15 22 39
35 java.lang 13 58 8 4 1 46 12
36 java.net 10 3 7 10 3 7
37 java.nio 15 6 13 2 6
38 java.sql 11 4 7
39 java.util 44 438 34 5 2 1 2 24 414
40 javax.faces.context 2 7 2 7
41 javax.jms 9 57 9 57
42 javax.json 123 100 23
43 javax.management.remote 2 2
44 javax.naming 7 6 1
45 javax.net.ssl 2 2
46 javax.script 1 1
47 javax.servlet 4 21 2 3 1 21 2
48 javax.validation 1 1 1 1
49 javax.ws.rs.client 1 1
50 javax.ws.rs.container 9 9
51 javax.ws.rs.core 3 149 1 2 94 55
52 javax.xml.transform 1 6 1 6
53 javax.xml.xpath 3 3
54 jodd.json 10 10
55 kotlin.jvm.internal 1 1
56 net.sf.saxon.s9api 5 5
57 ognl 6 6
58 okhttp3 2 47 2 22 25
59 org.apache.commons.codec 6 6
60 org.apache.commons.collections 800 17 783
61 org.apache.commons.collections4 800 17 783
62 org.apache.commons.io 104 561 89 15 547 14
63 org.apache.commons.jexl2 15 15
64 org.apache.commons.jexl3 15 15
65 org.apache.commons.lang3 424 293 131
66 org.apache.commons.logging 6 6
67 org.apache.commons.ognl 6 6
68 org.apache.commons.text 272 220 52
69 org.apache.directory.ldap.client.api 1 1
70 org.apache.hc.core5.function 1 1
71 org.apache.hc.core5.http 1 2 39 1 2 39
72 org.apache.hc.core5.net 2 2
73 org.apache.hc.core5.util 24 18 6
74 org.apache.http 27 3 70 25 2 3 62 8
75 org.apache.ibatis.jdbc 6 57 6 57
76 org.apache.log4j 11 11
77 org.apache.logging.log4j 359 8 359 4 4
78 org.apache.shiro.codec 1 1
79 org.apache.shiro.jndi 1 1
80 org.codehaus.groovy.control 1 1
81 org.dom4j 20 20
82 org.hibernate 7 7
83 org.jboss.logging 324 324
84 org.jdbi.v3.core 6 6
85 org.jooq 1 1
86 org.json 236 198 38
87 org.mvel2 16 16
88 org.scijava.log 13 13
89 org.slf4j 55 6 55 2 4
90 org.springframework.beans 30 30
91 org.springframework.boot.jdbc 1 1
92 org.springframework.cache 13 13
93 org.springframework.context 3 3
94 org.springframework.http 14 70 14 60 10
95 org.springframework.jdbc.core 10 10
96 org.springframework.jdbc.datasource 4 4
97 org.springframework.jdbc.object 9 9
98 org.springframework.jndi 1 1
99 org.springframework.ldap 47 33 14
100 org.springframework.security.web.savedrequest 6 6
101 org.springframework.ui 32 32
102 org.springframework.util 139 87 52
103 org.springframework.validation 13 13
104 org.springframework.web.client 13 3 13 3
105 org.springframework.web.context.request 8 8
106 org.springframework.web.multipart 12 13 12 13
107 org.springframework.web.reactive.function.client 2 2
108 org.springframework.web.util 163 138 25
109 org.xml.sax 1 1
110 org.xmlpull.v1 3 3
111 play.mvc 4 4
112 ratpack.core.form 3 3
113 ratpack.core.handling 6 4 6 4
114 ratpack.core.http 10 10 10 10
115 ratpack.exec 48 48
116 ratpack.form 3 3
117 ratpack.func 35 35
118 ratpack.handling 6 4 6 4
119 ratpack.http 10 10 10 10
120 ratpack.util 35 35
121 retrofit2 1 1

View File

@@ -7,7 +7,7 @@ Java framework & library support
:widths: auto
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE022` :sub:`Path injection`,`CWE036` :sub:`Path traversal`,`CWE079` :sub:`Cross-site scripting`,`CWE089` :sub:`SQL injection`,`CWE090` :sub:`LDAP injection`,`CWE094` :sub:`Code injection`,`CWE319` :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

View File

@@ -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),
}
}

View File

@@ -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()}\""
}

View File

@@ -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 =

View File

@@ -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) }

View File

@@ -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)
}
}
}

View File

@@ -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) }
}
}

View File

@@ -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)

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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