Compare commits

..

122 Commits

Author SHA1 Message Date
Nick Rolfe
740fd27707 Ruby: add dataflow for getters/setters defined using alias_attribute 2022-11-08 12:47:05 +00:00
Tony Torralba
d813590780 Merge pull request #11156 from atorralba/atorralba/swift/bitwise-operation
Swift: Add `BitwiseOperation.qll`
2022-11-08 12:15:00 +01:00
Tony Torralba
4411852e59 Add BitwiseOperation.qll 2022-11-08 11:33:10 +01:00
Jeroen Ketema
e00585ca24 Merge pull request #11154 from jketema/dataflow-test-fix
C++: Fix wrong return types and missing statement in dataflow test
2022-11-08 10:55:09 +01:00
AlexDenisov
d1848194eb Merge pull request #11152 from github/redsun82/swift-bitwise-test
Swift: add bitwise ops to `PrintAst` test
2022-11-08 10:25:48 +01:00
Tamás Vajk
38abd389eb Merge pull request #11045 from tamasvajk/kotlin-confusing-default
Kotlin: Excluded compiler generated methods from `java/confusing-method-signature`
2022-11-08 10:25:36 +01:00
Jeroen Ketema
0d4a2239fc C++: Fix wrong return types and missing statement in dataflow test 2022-11-08 09:55:10 +01:00
Paolo Tranquilli
072edad0fd Swift: accept new test changes 2022-11-08 09:30:25 +01:00
Erik Krogh Kristensen
c82410fd16 Merge pull request #10680 from erik-krogh/unsafeRbCmd
RB: add an unsafe-shell-command-construction query
2022-11-08 09:22:33 +01:00
Paolo Tranquilli
21adcca065 Swift: add bitwise ops to PrintAst test 2022-11-08 08:53:36 +01:00
Harry Maclean
8c8f1418d5 Merge pull request #11150 from hmac/try-fixup
Ruby: Cosmetic change
2022-11-08 12:19:47 +13:00
Harry Maclean
03aa8df8e2 Ruby: Cosmetic change 2022-11-08 10:24:21 +13:00
Harry Maclean
d392cdaab6 Merge pull request #11022 from hmac/try-code-injection
Ruby: try/try! as code execution
2022-11-08 09:42:52 +13:00
Tony Torralba
ef967b6a21 Merge pull request #10890 from atorralba/atorralba/android-startactivities-summaries
Java: Add flow summaries for startActivities
2022-11-07 18:06:30 +01:00
Alexander Eyers-Taylor
c6c4a7b14f Merge pull request #11068 from alexet/alexet/qlspec-instanceof
QL Spec: Add instanceof in classes
2022-11-07 16:15:09 +00:00
Erik Krogh Kristensen
3f871a08e2 apply suggestions from doc review
Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com>
2022-11-07 16:29:10 +01:00
Tamás Vajk
ed305d2699 Merge pull request #11032 from tamasvajk/kotlin-unused-for-loop-var
Kotlin: exclude loop variables on ranges from 'unused locals' check
2022-11-07 15:44:10 +01:00
Karim Ali
5766ff21d0 Merge pull request #10993 from karimhamdanali/swift-pbe-constant-salts
Swift: detect the use of constant salts
2022-11-07 16:22:41 +02:00
Stephan Brandauer
577f1a588b Merge pull request #11143 from github/codeql-ci/atm/release-0.4.0
JS: Bump version numbers of ML-powered packs after 0.4.0 release
2022-11-07 15:03:24 +01:00
Erik Krogh Kristensen
d67235b3c1 Merge pull request #11071 from erik-krogh/fixCanon
ReDoS: fix canonicalization in NfaUtils
2022-11-07 14:10:50 +01:00
github-actions[bot]
69df9f9daa JS: Bump version of ML-powered library and query packs to 0.4.1 2022-11-07 13:06:46 +00:00
github-actions[bot]
82277d8f56 JS: Bump minor version of ML-powered library and query packs 2022-11-07 13:00:28 +00:00
github-actions[bot]
268a990aa6 JS: Bump version of ML-powered model pack to 0.3.1 2022-11-07 13:00:28 +00:00
github-actions[bot]
a1e0bf022e ATM: Update model pack dependency of ML-powered model building and query packs 2022-11-07 13:00:27 +00:00
github-actions[bot]
be808deb59 JS: Bump minor version of ML-powered model pack 2022-11-07 12:59:44 +00:00
Chris Smowton
eb365c1d24 Merge pull request #11079 from smowton/smowton/test/test-java-extractor-vs-captured-type-variables
Java: Add test for multiply-bounded wildcards
2022-11-07 12:31:19 +00:00
Tamás Vajk
830be92f1d Merge pull request #11089 from tamasvajk/kotlin-enum-ctor-call
Kotlin: Extract missing arguments of enum constructor calls
2022-11-07 12:55:27 +01:00
AlexDenisov
f8e80f96ff Merge pull request #11124 from github/redsun82/swift-await
Swift: extract `AwaitExpr`
2022-11-07 12:52:42 +01:00
Karim Ali
1756feae71 address docs review 2022-11-07 13:20:02 +02:00
Paolo Tranquilli
b30a6d36b5 Swift: extract AwaitExpr 2022-11-07 12:08:51 +01:00
Paolo Tranquilli
b94066acd8 Merge pull request #11094 from github/redsun82/swift-translators
Swift: refactor visitors to use translations
2022-11-07 12:01:44 +01:00
Geoffrey White
7b62bed9db Merge pull request #10947 from karimhamdanali/swift-pbe-iterations
Swift: detect hash functions with low # of iterations
2022-11-07 10:38:29 +00:00
Chris Smowton
e877967a62 Add test verifying no malformed wildcards result from captured type variables with a Collection<? extends ...> type 2022-11-07 10:29:04 +00:00
Chris Smowton
d999c1d3dd Java: Add test for multiply-bounded wildcards
This exercises several cases of variables bounded both by a wildcard and by a bound on the type parameter, checking that the extractor strips the wildcards and captures to decide on a concrete type for the parameters and return values.
2022-11-07 10:29:04 +00:00
Chris Smowton
1cd30847f6 Merge pull request #11121 from smowton/smowton/fix/java-wildcard-extraction
Kotlin: fix extraction of Java nested wildcards; wildcards in return types
2022-11-07 10:23:02 +00:00
Chris Smowton
68face8d46 Merge pull request #11130 from smowton/smowton/fix/kotlin-always-extract-file-labels
Kotlin: always populate the `files` table
2022-11-07 10:14:41 +00:00
Jeroen Ketema
d62e3f6bc2 Merge pull request #11137 from jketema/dataflow-test-fixes
C++: Small fixes for the dataflow tests
2022-11-07 11:07:09 +01:00
Anders Schack-Mulligen
99ca28ea9b Merge pull request #10886 from aschackmull/dataflow/joinorders
Dataflow: Fix a couple of join-orders.
2022-11-07 11:05:29 +01:00
Chris Smowton
587aa93f6d Merge pull request #11105 from smowton/smowton/fix/use-defaults-method-to-implement-jvmoverloads
Kotlin: use `$default` functions to implement `@JvmOverloads`
2022-11-07 09:54:16 +00:00
Tamas Vajk
4e8d8a4de1 Add compilerGeneratedReason for enum constructor call arguments 2022-11-07 10:07:05 +01:00
Tamas Vajk
7d927a7396 Adjust enum constructor argument extraction based on review 2022-11-07 10:07:05 +01:00
Tamas Vajk
fb5b344427 Fix failing build on early kotlin versions 2022-11-07 10:07:05 +01:00
Tamas Vajk
44e70afa85 Kotlin: Extract missing arguments of enum constructor calls 2022-11-07 10:07:04 +01:00
Jeroen Ketema
291027ad82 C++: Fix return type in dataflow test 2022-11-07 09:42:54 +01:00
Jeroen Ketema
3b1feeef6d C++: Remove unneeded isAdditionalFlowStep from dataflow test
Since the introduction of flow through global variables these additional
steps are no longer needed.
2022-11-07 09:40:57 +01:00
Dave Bartolomeo
b8e1aa67d8 Merge pull request #11134 from github/post-release-prep/codeql-cli-2.11.3
Post-release preparation for codeql-cli-2.11.3
2022-11-05 13:54:49 -04:00
github-actions[bot]
fca754bddd Post-release preparation for codeql-cli-2.11.3 2022-11-05 14:30:48 +00:00
Mathias Vorreiter Pedersen
60ac031db4 Merge pull request #11036 from geoffw0/simplify3 2022-11-05 00:31:05 +00:00
Tiferet Gazit
5198ad7612 Merge pull request #11055 from github/tiferet/sink-classification-reasons
Sink endpoint characteristics
2022-11-04 11:24:08 -07:00
Henry Mercer
b32f4b844a Merge pull request #11118 from github/henrymercer/atm-check-queries-improvements
ATM: Miscellaneous improvements for the check queries workflow
2022-11-04 18:04:32 +00:00
tiferet
833041c62e Fix QLDoc style errors 2022-11-04 09:30:31 -07:00
tiferet
2aa4651534 Remove predicates not yet used from the current PR 2022-11-04 09:30:31 -07:00
tiferet
74c8bfff4f Minor changes from code review 2022-11-04 09:30:31 -07:00
tiferet
e60c016fc6 Format fixes 2022-11-04 09:30:31 -07:00
tiferet
cbf81b8839 Improve the import structure 2022-11-04 09:30:31 -07:00
tiferet
300456cd3e Enforce the abstraction over characteristics:
Make the implementations of specific `EndpointCharacteristic`s private.
2022-11-04 09:30:31 -07:00
tiferet
c0cc754fb5 Rename ClassificationReasons
Change the name to EndpointCharacteristics.
2022-11-04 09:30:30 -07:00
tiferet
a4939b91e7 Generalize the definition of a known sink:
If the list of reasons includes positive indicators with maximal confidence for this class, it's a known sink for the class.

This negates the need for each query config to define the isKnownSink predicate individually.
2022-11-04 09:30:29 -07:00
tiferet
08bbe596a2 Create the sink ClassificationReasons
Write the reasons that indicate that an endpoint is a sink for each sink type.

Also fix import error.
2022-11-04 09:30:29 -07:00
alexet
c07db098a7 QLSpec: Adress comments from review 2022-11-04 15:27:21 +00:00
Chris Smowton
8fd4041511 Kotlin: always populate the files table
Previously individual top-level file declarations relied on their corresponding file-class to declare their `File` instance, but this can be scuppered by a Java extractor replacing that file-class and identifying a different file location.
2022-11-04 15:00:27 +00:00
Henry Mercer
cbbff0c401 ATM: Rename workflow
Rename to take into account us now checking the results of the query
suite too.
2022-11-04 11:51:35 +00:00
Henry Mercer
87f7b65052 ATM: Check the results of the queries too 2022-11-04 11:51:35 +00:00
Anders Schack-Mulligen
a1dba82360 Dataflow: Sync. 2022-11-04 12:41:55 +01:00
Anders Schack-Mulligen
828d187198 Dataflow: Fix a couple of join-orders. 2022-11-04 12:41:55 +01:00
Chris Smowton
ca04779dfc Kotlin: fix extraction of Java nested wildcards; wildcards in return types
This fixes two mistakes: return-type extraction not imposing a wildcard where a Java prototype explicitly uses one, and nested wildcard detection quietly failing due to not looking through a `JavaWildcardType` correctly.

I add a variant of the `kotlin_java_lowering_wildcards` test where Java prototypes are only seen from Kotlin, to be sure extraction is working as expected.
2022-11-04 11:39:26 +00:00
Henry Mercer
fe27e09a07 ATM: Add codeowners entry for new workflow 2022-11-04 10:57:00 +00:00
Henry Mercer
05dd161d76 ATM: Use database analyze to check results interpretation too 2022-11-04 10:54:08 +00:00
Henry Mercer
7976d746b6 ATM: Simplify DB path definition and improve quoting 2022-11-04 10:49:25 +00:00
Henry Mercer
35a4d31519 ATM: Fix naming of query pack 2022-11-04 10:46:06 +00:00
Henry Mercer
f558e858e7 ATM: Install codeql using new input to fetch-codeql Action 2022-11-04 10:44:14 +00:00
Paolo Tranquilli
3a8efb3db1 Swift: make visit arguments pointers again 2022-11-04 06:06:05 +01:00
Geoffrey White
d69d289020 Swift: remove getArgumentByParamName (for now). 2022-11-03 18:56:13 +00:00
Paolo Tranquilli
e0eb820ef9 Swift: fix extraction of BuiltinIntegerLiteralType 2022-11-03 18:16:54 +01:00
Paolo Tranquilli
a1d798b817 Swift: make visit arguments references instead of pointers 2022-11-03 18:16:53 +01:00
Paolo Tranquilli
cc9dafffde Swift: encapsulate swift::ASTVisitor functionality 2022-11-03 18:16:53 +01:00
Paolo Tranquilli
7c9fffc201 Swift: rename all visitors to translators 2022-11-03 18:16:53 +01:00
Paolo Tranquilli
75f30a8f9c Swift: refactor ExprVisitor to use translations 2022-11-03 18:16:53 +01:00
Paolo Tranquilli
a6b1806e66 Swift: refactor TypeVisitor to use translations 2022-11-03 18:16:53 +01:00
Paolo Tranquilli
c8cb30f76e Swift: refactor StmtVisitor to use translations
Also make `visit` in `SwiftDispatcher` work on `const` pointers.

Also, fixed a bug where the guard of a `CaseLabelItem` was not being
extracted, hence the test updates.
2022-11-03 18:16:53 +01:00
Paolo Tranquilli
faf10294ed Swift: refactor PatternVisitor to use translations 2022-11-03 18:16:53 +01:00
Paolo Tranquilli
4702271102 Swift: add cfg.swift to AST tests 2022-11-03 18:16:53 +01:00
Chris Smowton
1ea87020c4 Kotlin: use $default functions to implement @JvmOverloads
This avoids extracting the default value expression in more than one place, which causes inconsistencies for e.g. anonymous classes, which expect to have a single `new` expression associated.
2022-11-03 14:48:36 +00:00
erik-krogh
f3741ff1e4 changes based on review 2022-11-03 09:41:05 +01:00
Tamas Vajk
e48dfcc5b1 Kotlin: exclude loop variables on ranges from 'unused locals' check 2022-11-02 17:34:59 +01:00
Tamas Vajk
a7cc8fced5 Adjust code based on review 2022-11-02 09:46:53 +01:00
Tamas Vajk
ec5ac17f87 Kotlin: Excluded compiler generated methods from java/confusing-method-signature 2022-11-02 09:40:31 +01:00
Tamas Vajk
556c199a89 Kotlin: Add test case for confusingly overloaded $default method 2022-11-02 09:40:31 +01:00
Geoffrey White
85e99feb49 Swift: Have swift/unsafe-webview-fetch use indices instead of parameter names. 2022-11-01 22:58:48 +00:00
Geoffrey White
d87117f623 Swift: Have swift/string-length-conflation use indices instead of parameter names. 2022-11-01 22:51:10 +00:00
erik-krogh
c15f63ce62 sync files 2022-11-01 21:35:27 +01:00
erik-krogh
15416a9c86 fix getCanonicalCharClass in NfaUtils 2022-11-01 21:35:07 +01:00
erik-krogh
78e35e2f29 add failing test 2022-11-01 21:33:19 +01:00
alexet
04a47093ee QL Spec: Add instanceof in classes 2022-11-01 18:31:43 +00:00
Karim Ali
3911f3b202 update query description following docs review 2022-10-31 13:54:35 +02:00
Karim Ali
76a330d4b9 update code example to be OWASP compliant 2022-10-31 13:52:49 +02:00
Karim Ali
723ca8ed88 update documentation following docs review 2022-10-31 13:50:30 +02:00
Harry Maclean
0dd63c007e Ruby: Add change note 2022-10-31 11:53:22 +13:00
Harry Maclean
fd61a5253d Ruby: Recognise try/try! as code executions 2022-10-31 11:53:22 +13:00
Geoffrey White
840b74dbb5 Swift: Add and use ApplyExpr.getArgumentByParamName. 2022-10-28 17:55:11 +01:00
Karim Ali
420c35d4a2 add a query that detects the use of constant salts 2022-10-26 15:32:59 +02:00
Karim Ali
18dd0f650c update iterations threshold to most recent OWASP recommendation
which is at least 120,000 iterations for secure password hashing
2022-10-25 14:01:40 +02:00
Karim Ali
408c7bebe5 fix .expected file 2022-10-25 13:24:37 +02:00
Karim Ali
e8f55b9f0d update output message 2022-10-25 13:24:37 +02:00
Karim Ali
c0ac29db16 clarify qhelp + add references to it 2022-10-25 13:24:37 +02:00
Karim Ali
4b7cb706f6 fix error in checking # of iterations
plus also simplify the pattern matching of the sink classes
2022-10-25 13:24:37 +02:00
Karim Ali
0d2e7d43b9 add expected output 2022-10-25 13:24:37 +02:00
Karim Ali
5179a99abb fix test cases to use the correct class name 2022-10-25 13:24:37 +02:00
Karim Ali
c4b2519e6c initial draft of the Swift query for CWE-916 2022-10-25 13:24:37 +02:00
erik-krogh
7797211118 Merge branch 'main' into unsafeRbCmd 2022-10-20 10:34:17 +02:00
Tony Torralba
0678b06a9b Apply review suggestions 2022-10-19 16:58:43 +02:00
Tony Torralba
25241276b0 Add change note 2022-10-19 16:29:36 +02:00
Tony Torralba
429bd5fbd8 Add flow summaries for startActivities
Uses SyntheticCallables and SyntheticGlobals to pair each startActivities call to getIntent calls in the components targeted by the intent(s).
2022-10-19 16:25:04 +02:00
erik-krogh
0220f0aa5c use type-tracking instead 2022-10-11 13:37:01 +02:00
erik-krogh
b64a1b7c42 add a missing qldoc 2022-10-11 13:26:04 +02:00
erik-krogh
cadb948d57 add change-note 2022-10-11 13:26:03 +02:00
erik-krogh
d427e55507 add qhelp 2022-10-11 13:26:03 +02:00
erik-krogh
557dd10896 add a rb/unsafe-shell-command-construction query 2022-10-11 13:26:01 +02:00
erik-krogh
0d5da42ddd add a getName() utility to DataFlow::ParameterNode 2022-10-11 13:05:22 +02:00
erik-krogh
75422dfa72 add library for reasoning about gems and .gemspec files 2022-10-11 13:05:19 +02:00
erik-krogh
99b90789e5 add .shellescape as a sanitizer for rb/command-injection 2022-10-11 13:05:19 +02:00
erik-krogh
b16b3c0394 move cwe-078 tests into subfolders 2022-10-11 13:05:19 +02:00
211 changed files with 7392 additions and 2263 deletions

View File

@@ -1,56 +0,0 @@
name: ATM Check Queries Run
env:
DB_PATH: test_db
ATM_MODEL_PACK: javascript/ql/experimental/adaptivethreatmodeling/src
QUERY_SUITE: codeql-suites/javascript-atm-code-scanning.qls
on:
pull_request:
paths:
- ".github/workflows/atm-check-queries-run.yml"
- "javascript/ql/experimental/adaptivethreatmodeling/**"
workflow_dispatch:
jobs:
run-atm-queries:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install CodeQL CLI
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh extensions install github/gh-codeql
gh codeql download
- name: Install ATM model pack
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -exu
# Install ATM model pack
gh codeql pack install ${ATM_MODEL_PACK}
# Retrieve model checksum
model_checksum=$(gh codeql resolve extensions ${ATM_MODEL_PACK}/${QUERY_SUITE} | jq -r '.models[0].checksum')
# Trust the model so that we can use it in the ATM boosted queries
mkdir -p "$HOME/.config/codeql"
echo "--insecurely-execute-ml-model-checksums ${model_checksum}" >> "$HOME/.config/codeql/config"
- name: Create test DB
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh codeql database create ${RUNNER_TEMP}/${DB_PATH} --source-root config/atm/ --language javascript
- name: Run ATM query suite
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh codeql database run-queries -vv -- ${RUNNER_TEMP}/${DB_PATH} ${ATM_MODEL_PACK}/${QUERY_SUITE}

View File

@@ -0,0 +1,93 @@
name: "ATM - Check query suite"
env:
QUERY_PACK: javascript/ql/experimental/adaptivethreatmodeling/src
QUERY_SUITE: codeql-suites/javascript-atm-code-scanning.qls
on:
pull_request:
paths:
- ".github/workflows/atm-check-query-suite.yml"
- "javascript/ql/experimental/adaptivethreatmodeling/**"
workflow_dispatch:
jobs:
atm-check-query-suite:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup CodeQL
uses: ./.github/actions/fetch-codeql
with:
channel: release
- name: Install ATM model
run: |
set -exu
# Install dependencies of ATM query pack, i.e. the ATM model
codeql pack install "${QUERY_PACK}"
# Retrieve model checksum
model_checksum=$(codeql resolve extensions "${QUERY_PACK}/${QUERY_SUITE}" | jq -r '.models[0].checksum')
# Trust the model so that we can use it in the ATM boosted queries
mkdir -p "$HOME/.config/codeql"
echo "--insecurely-execute-ml-model-checksums ${model_checksum}" >> "$HOME/.config/codeql/config"
- name: Create test DB
run: |
DB_PATH="${RUNNER_TEMP}/db"
echo "DB_PATH=${DB_PATH}" >> "${GITHUB_ENV}"
codeql database create "${DB_PATH}" --source-root config/atm --language javascript
- name: Run ATM query suite
run: |
SARIF_PATH="${RUNNER_TEMP}/sarif.json"
echo "SARIF_PATH=${SARIF_PATH}" >> "${GITHUB_ENV}"
codeql database analyze \
--format sarif-latest \
--output "${SARIF_PATH}" \
--sarif-group-rules-by-pack \
-vv \
-- \
"${DB_PATH}" \
"${QUERY_PACK}/${QUERY_SUITE}"
- name: Upload SARIF
uses: actions/upload-artifact@v3
with:
name: javascript-ml-powered-queries.sarif
path: "${{ env.SARIF_PATH }}"
retention-days: 5
- name: Check results
run: |
# We should run at least the ML-powered queries in `expected_rules`.
expected_rules="js/ml-powered/nosql-injection js/ml-powered/path-injection js/ml-powered/sql-injection js/ml-powered/xss"
for rule in ${expected_rules}; do
found_rule=$(jq --arg rule "${rule}" '[.runs[0].tool.extensions[].rules | select(. != null) |
flatten | .[].id] | any(. == $rule)' "${SARIF_PATH}")
if [[ "${found_rule}" != "true" ]]; then
echo "Expected SARIF output to contain rule '${rule}', but found no such rule."
exit 1
else
echo "Found rule '${rule}'."
fi
done
# We should have at least one alert from an ML-powered query.
num_alerts=$(jq '[.runs[0].results[] |
select(.properties.score != null and (.rule.id | startswith("js/ml-powered/")))] | length' \
"${SARIF_PATH}")
if [[ "${num_alerts}" -eq 0 ]]; then
echo "Expected to find at least one alert from an ML-powered query but found ${num_alerts}."
exit 1
else
echo "Found ${num_alerts} alerts from ML-powered queries.";
fi

View File

@@ -31,7 +31,7 @@ repos:
- id: sync-files
name: Fix files required to be identical
files: \.(qll?|qhelp|swift)$
files: \.(qll?|qhelp|swift)$|^config/identical-files\.json$
language: system
entry: python3 config/sync-files.py --latest
pass_filenames: false

View File

@@ -40,6 +40,7 @@ WORKSPACE.bazel @github/codeql-ci-reviewers
# Workflows
/.github/workflows/ @github/codeql-ci-reviewers
/.github/workflows/atm-* @github/codeql-ml-powered-queries-reviewers
/.github/workflows/go-* @github/codeql-go
/.github/workflows/js-ml-tests.yml @github/codeql-ml-powered-queries-reviewers
/.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers

View File

@@ -600,8 +600,12 @@
"swift/ql/test/extractor-tests/patterns/patterns.swift",
"swift/ql/test/library-tests/ast/patterns.swift"
],
"Swift control flow test file": [
"swift/ql/test/library-tests/controlflow/graph/cfg.swift",
"swift/ql/test/library-tests/ast/cfg.swift"
],
"IncompleteMultiCharacterSanitization JS/Ruby": [
"javascript/ql/lib/semmle/javascript/security/IncompleteMultiCharacterSanitizationQuery.qll",
"ruby/ql/lib/codeql/ruby/security/IncompleteMultiCharacterSanitizationQuery.qll"
]
}
}

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

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

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 0.4.3
version: 0.4.4-dev
groups:
- cpp
- queries

View File

@@ -329,21 +329,21 @@ namespace NestedTests {
namespace FlowThroughGlobals {
int globalVar;
int taintGlobal() {
void taintGlobal() {
globalVar = source();
}
int f() {
void f() {
sink(globalVar); // $ ir=333:17 ir=347:17 // tainted or clean? Not sure.
taintGlobal();
sink(globalVar); // $ ir=333:17 ir=347:17 MISSING: ast
}
int calledAfterTaint() {
void calledAfterTaint() {
sink(globalVar); // $ ir=333:17 ir=347:17 MISSING: ast
}
int taintAndCall() {
void taintAndCall() {
globalVar = source();
calledAfterTaint();
sink(globalVar); // $ ast ir=333:17 ir=347:17

View File

@@ -77,27 +77,9 @@ module IRTest {
)
}
override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(GlobalOrNamespaceVariable var | var.getName().matches("flowTestGlobal%") |
writesVariable(n1.asInstruction(), var) and
var = n2.asVariable()
or
readsVariable(n2.asInstruction(), var) and
var = n1.asVariable()
)
}
override predicate isBarrier(DataFlow::Node barrier) {
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier") or
barrier = DataFlow::InstructionBarrierGuard<testBarrierGuard/3>::getABarrierNode()
}
}
private predicate readsVariable(LoadInstruction load, Variable var) {
load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var
}
private predicate writesVariable(StoreInstruction store, Variable var) {
store.getDestinationAddress().(VariableAddressInstruction).getAstVariable() = var
}
}

View File

@@ -5,7 +5,7 @@ int source();
void sink(...);
bool random();
int test1() {
void test1() {
int x = source();
for (int i = 0; i < 10; i++) {
x = 0;
@@ -13,7 +13,7 @@ int test1() {
sink(x); // $ SPURIOUS: ir
}
int test2(int iterations) {
void test2(int iterations) {
int x = source();
for (int i = 0; i < iterations; i++) {
x = 0;
@@ -21,7 +21,7 @@ int test2(int iterations) {
sink(x); // $ ast,ir
}
int test3() {
void test3() {
int x = 0;
for (int i = 0; i < 10; i++) {
x = source();
@@ -29,7 +29,7 @@ int test3() {
sink(x); // $ ast,ir
}
int test4() {
void test4() {
int x = source();
for (int i = 0; i < 10; i++) {
if (random())
@@ -39,7 +39,7 @@ int test4() {
sink(x); // $ ast,ir
}
int test5() {
void test5() {
int x = source();
for (int i = 0; i < 10; i++) {
if (random())
@@ -49,7 +49,7 @@ int test5() {
sink(x); // $ ast,ir
}
int test6() {
void test6() {
int y;
int x = source();
for (int i = 0; i < 10 && (y = 1); i++) {
@@ -57,7 +57,7 @@ int test6() {
sink(x); // $ ast,ir
}
int test7() {
void test7() {
int y;
int x = source();
for (int i = 0; i < 10 && (y = 1); i++) {
@@ -66,7 +66,7 @@ int test7() {
sink(x); // $ SPURIOUS: ir
}
int test8() {
void test8() {
int x = source();
// It appears to the analysis that the condition can exit after `i < 10`
// without having assigned to `x`. That is an effect of how the
@@ -78,7 +78,7 @@ int test8() {
sink(x); // $ SPURIOUS: ast,ir
}
int test9() {
void test9() {
int y;
int x = source();
for (int i = 0; (y = 1) && i < 10; i++) {
@@ -86,21 +86,21 @@ int test9() {
sink(x); // $ ast,ir
}
int test10() {
void test10() {
int x = source();
for (int i = 0; (x = 1) && i < 10; i++) {
}
sink(x); // no flow
}
int test10(int b, int d) {
void test10(int b, int d) {
int i = 0;
int x = source();
if (b)
goto L;
for (; i < 10; i += d) {
x = 0;
L:
L: ;
}
sink(x); // $ ir MISSING: ast
}

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-all
version: 0.4.3
version: 0.4.4-dev
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-queries
version: 0.4.3
version: 0.4.4-dev
groups:
- csharp
- queries

View File

@@ -819,13 +819,15 @@ A class definition has the following syntax:
::
class ::= qldoc? annotations "class" classname "extends" type ("," type)* "{" member* "}"
class ::= qldoc? annotations "class" classname ("extends" type ("," type)*)? ("instanceof" type ("," type)*)? "{" member* "}"
The identifier following the ``class`` keyword is the name of the class.
The types specified after the ``extends`` keyword are the *base types* of the class.
A class domain type is said to *inherit* from the base types of the associated class type, a character type is said to *inherit* from its associated class domain type and a class type is said to *inherit* from its associated character type. In addition, inheritance is transitive: If a type ``A`` inherits from a type ``B``, and ``B`` inherits from a type ``C``, then ``A`` inherits from ``C``.
The types specified after the ``instanceof`` keyword are the *instanceof types* of the class.
A class type is said to *inherit* from the base types. In addition, inheritance is transitive: If a type ``A`` inherits from a type ``B``, and ``B`` inherits from a type ``C``, then ``A`` inherits from ``C``.
A class adds a mapping from the class name to the class declaration to the current module's declared type environment.
@@ -833,6 +835,20 @@ A valid class can be annotated with ``abstract``, ``final``, ``library``, and ``
A valid class may not inherit from a final class, from itself, or from more than one primitive type.
A valid class must have at least one base type or instanceof type.
Class dependencies
~~~~~~~~~~~~~~~~~~
The program is invalid if there is a cycle of class dependencies.
The following are class dependencies:
- ``C`` depends on ``C.C``
- ``C.C`` depends on ``C.extends``
- If ``C`` is abstract then it depends on all classes ``D`` such that ``C`` is a base type of ``D``.
- ``C.extends`` depends on ``D.D`` for each base type ``D`` of ``C``.
- ``C.extends`` depends on ``D`` for each instanceof type ``D`` of ``C``.
Class environments
~~~~~~~~~~~~~~~~~~
@@ -848,7 +864,9 @@ For each of member predicates and fields a class *inherits* and *declares*, and
The program is invalid if any of these environments is not definite.
For each of member predicates and fields a domain type *exports* an environment. This is the union of the exported ``X`` environments of types the class inherits from, excluding any elements that are ``overridden`` by another element.
For each of member predicates and fields a domain type *exports* an environment. We say the *exported X extends environment* is the union of the exported ``X`` environments of types the class inherits from, excluding any elements that are ``overridden`` by another element.
We say the *exported X instanceof environement* is the union of the exported ``X`` environments of types that a instanceof type inherits from, excluding any elements that are ``overridden`` by another element.
The *exported X environment* of the domain type is the union of the exported ``X`` extends environment and the exported ``X`` instanceof environement.
Members
~~~~~~~
@@ -1090,11 +1108,7 @@ A super expression has the following syntax:
super_expr ::= "super" | type "." "super"
For a super expression to be valid, the ``this`` keyword must have a type and value in the typing environment. The type of the expression is the same as the type of ``this`` in the typing environment.
A super expression may only occur in a QL program as the receiver expression for a predicate call.
If a super expression includes a ``type``, then that type must be a class that the enclosing class inherits from.
For a super expression to be valid, the ``this`` keyword must have a type and value in the typing environment. The type of the expression is the same as the domain type of the type of ``this`` in the typing environment.
The value of a super expression is the same as the value of ``this`` in the named tuple.
@@ -1147,13 +1161,6 @@ A valid call with results *resolves* to a set of predicates. The ways a call can
- If the call has no receiver and the predicate name is a selection identifier, then the qualifier is resolved as a module (see "`Module resolution <#module-resolution>`__"). The identifier is then resolved in the exported predicate environment of the qualifier module.
- If the call has a super expression as the receiver, then it resolves to a member predicate in a class that the enclosing class inherits from:
- If the super expression is unqualified and there is a single class that the current class inherits from, then the super-class is that class.
- If the super expression is unqualified and there are multiple classes that the current class inherits from, then the super-class is the domain type.
- Otherwise, the super-class is the class named by the qualifier of the super expression.
The predicate is resolved by looking up its name and arity in the exported predicate environment of the super-class.
- If the type of the receiver is the same as the enclosing class, the predicate is resolved by looking up its name and arity in the visible predicate environment of the class.
- If the type of the receiver is not the same as the enclosing class, the predicate is resolved by looking up its name and arity in the exported predicate environment of the class or domain type.
@@ -1177,11 +1184,20 @@ If the resolved predicate is built in, then the call may not include a closure.
If the call includes a closure, then all declared predicate arguments, the enclosing type of the declaration (if it exists), and the result type of the declaration (if it exists) must be compatible. If one of those types is a subtype of ``int``, then all the other arguments must be a subtype of ``int``.
A call to a member predicate may be a *direct* call:
- If the receiver is not a super expression it is not direct.
- If the receiver is ``A.super`` and ``A`` is an instanceof type and not a base type then it is not direct.
- If the receiver is ``A.super`` and ``A`` is a base type type and not an instanceof type then it is direct.
- If the receiver is ``A.super`` and ``A`` is a base type and an instanceof type then the call is not valid.
- If the receiver is ``super`` and the member predicate is in the exported member predicate environment of an instanceof type and not in the exported member predicate environment of a base type then it isn't direct.
- If the receiver is ``super`` and the member predicate is in the exported member predicate environment of a base type and not in the exported member predicate environment of an instanceof type then it is direct.
- If the receiver is ``super`` and the member predicate is in the exported member predicate environment of a base type and in the exported member predicate environment of an instanceof type then the call is not valid.
If the call resolves to a member predicate, then the *receiver values* are as follows. If the call has a receiver, then the receiver values are the values of that receiver. If the call does not have a receiver, then the single receiver value is the value of ``this`` in the contextual named tuple.
The *tuple prefixes* of a call with results include one value from each of the argument expressions' values, in the same order as the order of the arguments. If the call resolves to a non-member predicate, then those values are exactly the tuple prefixes of the call. If the call instead resolves to a member predicate, then the tuple prefixes additionally include a receiver value, ordered before the argument values.
The *matching tuples* of a call with results are all ordered tuples that are one of the tuple prefixes followed by any value of the same type as the call. If the call has no closure, then all matching tuples must additionally satisfy the resolved predicate of the call, unless the receiver is a super expression, in which case they must *directly* satisfy the resolved predicate of the call. If the call has a ``*`` or ``+`` closure, then the matching tuples must satisfy or directly satisfy the associated closure of the resolved predicate.
The *matching tuples* of a call with results are all ordered tuples that are one of the tuple prefixes followed by any value of the same type as the call. If the call has no closure, then all matching tuples must additionally satisfy the resolved predicate of the call, unless the call is direct in which case they must *directly* satisfy the resolved predicate of the call. If the call has a ``*`` or ``+`` closure, then the matching tuples must satisfy or directly satisfy the associated closure of the resolved predicate.
The values of a call with results are the final elements of each of the call's matching tuples.
@@ -1534,13 +1550,15 @@ The identifier is called the *predicate name* of the call.
A call must resolve to a predicate, using the same definition of resolve as for calls with results (see "`Calls with results <#calls-with-results>`__").
A call may be direct using the same definition of direct as for calls with results (see "`Calls with results <#calls-with-results>`__").
The resolved predicate must not have a result type.
If the resolved predicate is a built-in member predicate of a primitive type, then the call may not include a closure. If the call does have a closure, then the call must resolve to a predicate with relational arity of 2.
The *candidate tuples* of a call are the ordered tuples formed by selecting a value from each of the arguments of the call.
If the call has no closure, then it matches whenever one of the candidate tuples satisfies the resolved predicate of the call, unless the call has a super expression as a receiver, in which case the candidate tuple must *directly* satisfy the resolved predicate. If the call has ``*`` or ``+`` closure, then the call matches whenever one of the candidate tuples satisfies or directly satisfies the associated closure of the resolved predicate.
If the call has no closure, then it matches whenever one of the candidate tuples satisfies the resolved predicate of the call, unless the call is direct, in which case the candidate tuple must *directly* satisfy the resolved predicate. If the call has ``*`` or ``+`` closure, then the call matches whenever one of the candidate tuples satisfies or directly satisfies the associated closure of the resolved predicate.
Disambiguation of formulas
~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1926,10 +1944,12 @@ Predicates, and types can *depend* and *strictly depend* on each other. Such dep
- A predicate containing a predicate call depends on the predicate to which the call resolves. If the call has negative or zero polarity then the dependency is strict.
- A predicate containing a predicate call, which resolves to a member predicate and does not have a ``super`` expression as a qualifier, depends on the dispatch dependencies of the root definitions of the target of the call. If the call has negative or zero polarity then the dependencies are strict. The predicate strictly depends on the strict dispatch dependencies of the root definitions.
- A predicate containing a predicate call, which resolves to a member predicate, where the call is not direct, depends on the dispatch dependencies of the root definitions of the target of the call. If the call has negative or zero polarity then the dependencies are strict. The predicate strictly depends on the strict dispatch dependencies of the root definitions.
- For each class ``C`` in the program, for each base class ``B`` of ``C``, ``C.extends`` depends on ``B.B``.
- For each class ``C`` in the program, for each instanceof type ``B`` of ``C``, ``C.extends`` depends on ``B``.
- For each class ``C`` in the program, for each base type ``B`` of ``C`` that is not a class type, ``C.extends`` depends on ``B``.
- For each class ``C`` in the program, ``C.class`` depends on ``C.C``.
@@ -1976,6 +1996,7 @@ Each layer of the stratification is *populated* in order. To populate a layer, e
- To populate the type ``C.extends`` for a class ``C``, identify each named tuple that has the following properties:
- The value of ``this`` is in all non-class base types of ``C``.
- The value of ``this`` is in all instanceof types of ``C``.
- The keys of the tuple are ``this`` and the union of the public fields from each base type.
- For each class base type ``B`` of ``C`` there is a named tuple with variables from the public fields of ``B`` and ``this`` that the given tuple and some tuple in ``B.B`` both extend.
@@ -2060,7 +2081,7 @@ The complete grammar for QL is as follows:
| "{" formula "}"
| "=" literalId "(" (predicateRef "/" int ("," predicateRef "/" int)*)? ")" "(" (exprs)? ")"
class ::= qldoc? annotations "class" classname "extends" type ("," type)* "{" member* "}"
class ::= qldoc? annotations "class" classname ("extends" type ("," type)*)? ("instanceof" type ("," type)*)? "{" member* "}"
member ::= character | predicate | field

View File

@@ -1,5 +1,5 @@
name: codeql/go-all
version: 0.3.3
version: 0.3.4-dev
groups: go
dbscheme: go.dbscheme
extractor: go

View File

@@ -1,5 +1,5 @@
name: codeql/go-queries
version: 0.3.3
version: 0.3.4-dev
groups:
- go
- queries

View File

@@ -80,7 +80,7 @@ class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: Stri
}
// Now elevate to a SourceFileTrapWriter, and populate the
// file information if needed:
val ftw = tw.makeFileTrapWriter(binaryPath, irDecl is IrClass)
val ftw = tw.makeFileTrapWriter(binaryPath, true)
val fileExtractor = KotlinFileExtractor(logger, ftw, null, binaryPath, manager, this, primitiveTypeMapping, pluginContext, KotlinFileExtractor.DeclarationStack(), globalExtensionState)

View File

@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyFunction
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
@@ -1051,8 +1052,8 @@ open class KotlinFileExtractor(
if (!f.hasAnnotation(jvmOverloadsFqName))
return
fun extractGeneratedOverload(paramList: List<IrElement>) {
val overloadParameters = paramList.filterIsInstance<IrValueParameter>()
fun extractGeneratedOverload(paramList: List<IrValueParameter?>) {
val overloadParameters = paramList.filterNotNull()
// Note `overloadParameters` have incorrect parents and indices, since there is no actual IrFunction describing the required synthetic overload.
// We have to use the `overriddenAttributes` element of `DeclarationStackAdjuster` to fix up references to these parameters while we're extracting
// these synthetic overloads.
@@ -1072,67 +1073,33 @@ open class KotlinFileExtractor(
DeclarationStackAdjuster(f, overriddenAttributes).use {
fun extractNormalArgs(argParentId: Label<out DbExprparent>, idxOffset: Int, enclosingStmtId: Label<out DbStmt>) {
paramList.forEachIndexed { idx, param ->
when(param) {
is IrValueParameter -> {
// Forward a parameter:
val syntheticParamId = useValueParameter(param, overloadId)
extractVariableAccess(syntheticParamId, param.type, realFunctionLocId, argParentId, idxOffset + idx, overloadId, enclosingStmtId)
}
is IrExpression -> {
// Supply a default argument:
extractExpressionExpr(param, overloadId, argParentId, idxOffset + idx, enclosingStmtId)
}
else -> {
logger.errorElement("Unexpected parameter list entry", param)
}
}
}
}
// Create a synthetic function body that calls the corresponding $default function:
val regularArgs = paramList.map { it?.let { p -> IrGetValueImpl(-1, -1, p.symbol) } }
// Create a synthetic function body that calls the real function supplying default arguments where required:
if (f is IrConstructor) {
val blockId = extractBlockBody(overloadId, realFunctionLocId)
val constructorCallId = tw.getFreshIdLabel<DbConstructorinvocationstmt>()
tw.writeStmts_constructorinvocationstmt(constructorCallId, blockId, 0, overloadId)
tw.writeHasLocation(constructorCallId, realFunctionLocId)
tw.writeCallableBinding(constructorCallId, useFunction(f))
tw.writeCallableBinding(constructorCallId, getDefaultsMethodLabel(f))
extractNormalArgs(constructorCallId, 0, constructorCallId)
extractDefaultsCallArguments(constructorCallId, f, overloadId, constructorCallId, regularArgs, null, null)
} else {
val dispatchReceiver = f.dispatchReceiverParameter?.let { IrGetValueImpl(-1, -1, it.symbol) }
val extensionReceiver = f.extensionReceiverParameter?.let { IrGetValueImpl(-1, -1, it.symbol) }
extractExpressionBody(overloadId, realFunctionLocId).also { returnId ->
extractRawMethodAccess(
f,
realFunctionLocId,
f.returnType,
overloadId,
returnId,
0,
returnId,
f.valueParameters.size,
{ argParentId, idxOffset ->
extractNormalArgs(argParentId, idxOffset, returnId)
},
f.dispatchReceiverParameter?.type,
f.dispatchReceiverParameter?.let { { callId ->
extractThisAccess(it.type, overloadId, callId, -1, returnId, realFunctionLocId)
} },
f.extensionReceiverParameter?.let { { argParentId ->
val syntheticParamId = useValueParameter(it, overloadId)
extractVariableAccess(syntheticParamId, it.type, realFunctionLocId, argParentId, 0, overloadId, returnId)
} }
)
extractsDefaultsCall(f, realFunctionLocId, f.returnType, overloadId, returnId, 0, returnId, regularArgs, dispatchReceiver, extensionReceiver)
}
}
}
}
}
val paramList: MutableList<IrElement> = f.valueParameters.toMutableList()
for (n in (paramList.size - 1) downTo 0) {
(paramList[n] as? IrValueParameter)?.defaultValue?.expression?.let {
paramList[n] = it // Replace the last parameter that has a default with that default value.
val paramList: MutableList<IrValueParameter?> = f.valueParameters.toMutableList()
for (n in (f.valueParameters.size - 1) downTo 0) {
if (f.valueParameters[n].defaultValue != null) {
paramList[n] = null // Remove this parameter, to be replaced by a default value
extractGeneratedOverload(paramList)
}
}
@@ -2122,7 +2089,7 @@ open class KotlinFileExtractor(
private fun extractCallValueArguments(callId: Label<out DbExprparent>, valueArguments: List<IrExpression?>, enclosingStmt: Label<out DbStmt>, enclosingCallable: Label<out DbCallable>, idxOffset: Int, extractVarargAsArray: Boolean = false) {
var i = 0
valueArguments.forEach { arg ->
if(arg != null) {
if (arg != null) {
if (arg is IrVararg && !extractVarargAsArray) {
arg.elements.forEachIndexed { varargNo, vararg -> extractVarargElement(vararg, enclosingCallable, callId, i + idxOffset + varargNo, enclosingStmt) }
i += arg.elements.size
@@ -3063,15 +3030,31 @@ open class KotlinFileExtractor(
val isAnonymous = eType.isAnonymous
val locId = tw.getLocation(e)
val valueArgs = (0 until e.valueArgumentsCount).map { e.getValueArgument(it) }
// For now, don't try to use default methods for enum constructor calls,
// which have null arguments even though the parameters don't give default values.
val id = if (e !is IrEnumConstructorCall && callUsesDefaultArguments(e.symbol.owner, valueArgs)) {
extractNewExpr(getDefaultsMethodLabel(e.symbol.owner).cast(), type, locId, parent, idx, callable, enclosingStmt).also {
extractDefaultsCallArguments(it, e.symbol.owner, callable, enclosingStmt, valueArgs, null, null)
}
} else {
extractNewExpr(e.symbol.owner, eType.arguments, type, locId, parent, idx, callable, enclosingStmt).also {
extractCallValueArguments(it, e, enclosingStmt, callable, 0)
val realCallTarget = e.symbol.owner.realOverrideTarget
// Generated constructor calls to kotlin.Enum have no arguments in IR, but the constructor takes two parameters.
if (e is IrEnumConstructorCall &&
realCallTarget is IrConstructor &&
realCallTarget.parentClassOrNull?.fqNameWhenAvailable?.asString() == "kotlin.Enum" &&
realCallTarget.valueParameters.size == 2 &&
realCallTarget.valueParameters[0].type == pluginContext.irBuiltIns.stringType &&
realCallTarget.valueParameters[1].type == pluginContext.irBuiltIns.intType) {
val id0 = extractNull(pluginContext.irBuiltIns.stringType, locId, it, 0, callable, enclosingStmt)
tw.writeCompiler_generated(id0, CompilerGeneratedKinds.ENUM_CONSTRUCTOR_ARGUMENT.kind)
val id1 = extractConstantInteger(0, locId, it, 1, callable, enclosingStmt)
tw.writeCompiler_generated(id1, CompilerGeneratedKinds.ENUM_CONSTRUCTOR_ARGUMENT.kind)
} else {
extractCallValueArguments(it, e, enclosingStmt, callable, 0)
}
}
}
@@ -3396,6 +3379,14 @@ open class KotlinFileExtractor(
extractExprContext(it, locId, callable, enclosingStmt)
}
private fun extractNull(t: IrType, locId: Label<DbLocation>, parent: Label<out DbExprparent>, idx: Int, callable: Label<out DbCallable>, enclosingStmt: Label<out DbStmt>) =
tw.getFreshIdLabel<DbNullliteral>().also {
val type = useType(t)
tw.writeExprs_nullliteral(it, type.javaResult.id, parent, idx)
tw.writeExprsKotlinType(it, type.kotlinResult.id)
extractExprContext(it, locId, callable, enclosingStmt)
}
private fun extractAssignExpr(type: IrType, locId: Label<DbLocation>, parent: Label<out DbExprparent>, idx: Int, callable: Label<out DbCallable>, enclosingStmt: Label<out DbStmt>) =
tw.getFreshIdLabel<DbAssignexpr>().also {
val typeResults = useType(type)
@@ -3614,12 +3605,7 @@ open class KotlinFileExtractor(
tw.writeNamestrings(v.toString(), v.toString(), id)
}
v == null -> {
val id = tw.getFreshIdLabel<DbNullliteral>()
val type = useType(e.type) // class;kotlin.Nothing
val locId = tw.getLocation(e)
tw.writeExprs_nullliteral(id, type.javaResult.id, exprParent.parent, exprParent.idx)
tw.writeExprsKotlinType(id, type.kotlinResult.id)
extractExprContext(id, locId, callable, exprParent.enclosingStmt)
extractNull(e.type, tw.getLocation(e), exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt)
}
else -> {
logger.errorElement("Unrecognised IrConst: " + v.javaClass, e)
@@ -5516,5 +5502,6 @@ open class KotlinFileExtractor(
JVMOVERLOADS_METHOD(9),
DEFAULT_ARGUMENTS_METHOD(10),
INTERFACE_FORWARDER(11),
ENUM_CONSTRUCTOR_ARGUMENT(12),
}
}

View File

@@ -963,9 +963,9 @@ open class KotlinUsesExtractor(
private fun wildcardAdditionAllowed(v: Variance, t: IrType, addByDefault: Boolean, javaVariance: Variance?) =
when {
t.hasAnnotation(jvmWildcardAnnotation) -> true
!addByDefault -> false
// If a Java declaration specifies a variance, introduce it even if it's pointless (e.g. ? extends FinalClass, or ? super Object)
javaVariance == v -> true
!addByDefault -> false
v == Variance.IN_VARIANCE -> !(t.isNullableAny() || t.isAny())
v == Variance.OUT_VARIANCE -> extendsAdditionAllowed(t)
else -> false
@@ -1006,8 +1006,9 @@ open class KotlinUsesExtractor(
null
} ?: t
private fun getJavaTypeArgument(jt: JavaType, idx: Int) =
private fun getJavaTypeArgument(jt: JavaType, idx: Int): JavaType? =
when(jt) {
is JavaWildcardType -> jt.bound?.let { getJavaTypeArgument(it, idx) }
is JavaClassifierType -> jt.typeArguments.getOrNull(idx)
is JavaArrayType -> if (idx == 0) jt.componentType else null
else -> null

View File

@@ -0,0 +1,9 @@
import java
from Call call, Callable c
where
count(call.getAnArgument()) != c.getNumberOfParameters() and
call.getCallee() = c and
not exists(Parameter p | c.getAParameter() = p and p.isVarargs()) and
call.getFile().isKotlinSourceFile()
select call, c, count(call.getAnArgument()), c.getNumberOfParameters()

View File

@@ -0,0 +1,18 @@
public class JavaDefns2 {
// Currently known not to work: the Comparable<? extends X> case, which Kotlin sees as Comparable<*> because the
// wildcard goes the opposite direction to the variance declared on Comparable's type parameter.
public static void takesComparable(Comparable<CharSequence> invar, Comparable<? super CharSequence> contravar) { }
public static void takesNestedComparable(Comparable<Comparable<? super CharSequence>> innerContravar, Comparable<? super Comparable<CharSequence>> outerContravar) { }
public static void takesArrayOfComparable(Comparable<CharSequence>[] invar, Comparable<? super CharSequence>[] contravar) { }
public static Comparable<? super CharSequence> returnsWildcard() { return null; }
public static Comparable<CharSequence> returnsInvariant() { return null; }
public JavaDefns2(Comparable<CharSequence> invar, Comparable<? super CharSequence> contravar) { }
}

View File

@@ -7,4 +7,6 @@ fun user() {
JavaDefns.takesArrayOfComparable(acs, acs)
val constructed = JavaDefns(cs, cs)
JavaDefns2.takesComparable(cs, cs)
}

View File

@@ -8,6 +8,16 @@
| JavaDefns | takesComparable | invar | Comparable<CharSequence> |
| JavaDefns | takesNestedComparable | innerContravar | Comparable<Comparable<? super CharSequence>> |
| JavaDefns | takesNestedComparable | outerContravar | Comparable<? super Comparable<CharSequence>> |
| JavaDefns2 | JavaDefns2 | p0 | Comparable<CharSequence> |
| JavaDefns2 | JavaDefns2 | p1 | Comparable<? super CharSequence> |
| JavaDefns2 | returnsInvariant | return | Comparable<CharSequence> |
| JavaDefns2 | returnsWildcard | return | Comparable<? super CharSequence> |
| JavaDefns2 | takesArrayOfComparable | p0 | Comparable<CharSequence>[] |
| JavaDefns2 | takesArrayOfComparable | p1 | Comparable<? super CharSequence>[] |
| JavaDefns2 | takesComparable | p0 | Comparable<CharSequence> |
| JavaDefns2 | takesComparable | p1 | Comparable<? super CharSequence> |
| JavaDefns2 | takesNestedComparable | p0 | Comparable<Comparable<? super CharSequence>> |
| JavaDefns2 | takesNestedComparable | p1 | Comparable<? super Comparable<CharSequence>> |
| KotlinDefns | returnsContravar | return | Comparable<CharSequence> |
| KotlinDefns | returnsContravarForced | return | Comparable<? super CharSequence> |
| KotlinDefns | returnsCovar | return | List<CharSequence> |

View File

@@ -1,3 +1,5 @@
from create_database_utils import *
# Compile the JavaDefns2 copy outside tracing, to make sure the Kotlin view of it matches the Java view seen by the traced javac compilation of JavaDefns.java below.
runSuccessfully(["javac", "JavaDefns2.java"])
run_codeql_database_create(["kotlinc kotlindefns.kt", "javac JavaUser.java JavaDefns.java -cp .", "kotlinc -cp . kotlinuser.kt"], lang="java")

View File

@@ -1,7 +1,7 @@
import java
predicate isInterestingClass(Class c) {
[c, c.(NestedType).getEnclosingType()].getName().matches(["KotlinDefns%", "JavaDefns"])
[c, c.(NestedType).getEnclosingType()].getName().matches(["KotlinDefns%", "JavaDefns%"])
}
from Callable c, string paramOrReturnName, Type paramOrReturnType

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added data flow summaries for tainted Android intents sent to activities via `Activity.startActivities`.

View File

@@ -1,5 +1,5 @@
name: codeql/java-all
version: 0.4.3
version: 0.4.4-dev
groups: java
dbscheme: config/semmlecode.dbscheme
extractor: java

View File

@@ -69,6 +69,8 @@ class Element extends @element, Top {
i = 10 and result = "Forwarder for Kotlin calls that need default arguments filling in"
or
i = 11 and result = "Forwarder for a Kotlin class inheriting an interface default method"
or
i = 12 and result = "Argument for enum constructor call"
)
}
}

View File

@@ -26,6 +26,9 @@ module SummaryComponent {
/** Gets a summary component for `Element`. */
SummaryComponent element() { result = content(any(CollectionContent c)) }
/** Gets a summary component for `ArrayElement`. */
SummaryComponent arrayElement() { result = content(any(ArrayContent c)) }
/** Gets a summary component for `MapValue`. */
SummaryComponent mapValue() { result = content(any(MapValueContent c)) }
@@ -52,6 +55,11 @@ module SummaryComponentStack {
result = push(SummaryComponent::element(), object)
}
/** Gets a stack representing `ArrayElement` of `object`. */
SummaryComponentStack arrayElementOf(SummaryComponentStack object) {
result = push(SummaryComponent::arrayElement(), object)
}
/** Gets a stack representing `MapValue` of `object`. */
SummaryComponentStack mapValueOf(SummaryComponentStack object) {
result = push(SummaryComponent::mapValue(), object)

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -2629,6 +2629,7 @@ private predicate evalUnfold(AccessPathApprox apa, boolean unfold, Configuration
/**
* Gets the number of `AccessPath`s that correspond to `apa`.
*/
pragma[assume_small_delta]
private int countAps(AccessPathApprox apa, Configuration config) {
evalUnfold(apa, false, config) and
result = 1 and
@@ -2647,6 +2648,7 @@ private int countAps(AccessPathApprox apa, Configuration config) {
* that it is expanded to a precise head-tail representation.
*/
language[monotonicAggregates]
pragma[assume_small_delta]
private int countPotentialAps(AccessPathApprox apa, Configuration config) {
apa instanceof AccessPathApproxNil and result = 1
or
@@ -2681,6 +2683,7 @@ private newtype TAccessPath =
}
private newtype TPathNode =
pragma[assume_small_delta]
TPathNodeMid(
NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap, Configuration config
) {
@@ -2778,6 +2781,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
override AccessPathFrontHead getFront() { result = TFrontHead(head) }
pragma[assume_small_delta]
override AccessPathApproxCons getApprox() {
result = TConsNil(head, tail.(AccessPathNil).getType())
or
@@ -2786,6 +2790,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
result = TCons1(head, this.length())
}
pragma[assume_small_delta]
override int length() { result = 1 + tail.length() }
private string toStringImpl(boolean needsSuffix) {
@@ -3155,6 +3160,7 @@ private predicate pathNode(
* Holds if data may flow from `mid` to `node`. The last step in or out of
* a callable is recorded by `cc`.
*/
pragma[assume_small_delta]
pragma[nomagic]
private predicate pathStep(
PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, AccessPath ap

View File

@@ -1,7 +1,10 @@
import java
private import semmle.code.java.frameworks.android.Android
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSteps
private import semmle.code.java.dataflow.FlowSummary
private import semmle.code.java.dataflow.internal.BaseSSA as BaseSsa
/** The class `android.content.Intent`. */
class TypeIntent extends Class {
@@ -242,19 +245,52 @@ private class StartComponentMethodAccess extends MethodAccess {
/** Gets the intent argument of this call. */
Argument getIntentArg() {
result.getType() instanceof TypeIntent and
(
result.getType() instanceof TypeIntent or
result.getType().(Array).getElementType() instanceof TypeIntent
) and
result = this.getAnArgument()
}
/** Holds if this targets a component of type `targetType`. */
predicate targetsComponentType(RefType targetType) {
predicate targetsComponentType(AndroidComponent targetType) {
exists(NewIntent newIntent |
DataFlow::localExprFlow(newIntent, this.getIntentArg()) and
reaches(newIntent, this.getIntentArg()) and
newIntent.getClassArg().getType().(ParameterizedType).getATypeArgument() = targetType
)
}
}
/**
* Holds if `src` reaches the intent argument `arg` of `StartComponentMethodAccess`
* through intra-procedural steps.
*/
private predicate reaches(Expr src, Argument arg) {
any(StartComponentMethodAccess ma).getIntentArg() = arg and
src = arg
or
exists(Expr mid, BaseSsa::BaseSsaVariable ssa, BaseSsa::BaseSsaUpdate upd |
reaches(mid, arg) and
mid = ssa.getAUse() and
upd = ssa.getAnUltimateLocalDefinition() and
src = upd.getDefiningExpr().(VariableAssign).getSource()
)
or
exists(CastingExpr e | e.getExpr() = src | reaches(e, arg))
or
exists(ChooseExpr e | e.getAResultExpr() = src | reaches(e, arg))
or
exists(AssignExpr e | e.getSource() = src | reaches(e, arg))
or
exists(ArrayCreationExpr e | e.getInit().getAnInit() = src | reaches(e, arg))
or
exists(StmtExpr e | e.getResultExpr() = src | reaches(e, arg))
or
exists(NotNullExpr e | e.getExpr() = src | reaches(e, arg))
or
exists(WhenExpr e | e.getBranch(_).getAResult() = src | reaches(e, arg))
}
/**
* A value-preserving step from the intent argument of a `startActivity` call to
* a `getIntent` call in the activity the intent targeted in its constructor.
@@ -271,6 +307,87 @@ private class StartActivityIntentStep extends AdditionalValueStep {
}
}
/**
* Holds if `targetType` is targeted by an existing `StartComponentMethodAccess` call
* and it's identified by `id`.
*/
private predicate isTargetableType(AndroidComponent targetType, string id) {
exists(StartComponentMethodAccess ma | ma.targetsComponentType(targetType)) and
targetType.getQualifiedName() = id
}
private class StartActivitiesSyntheticCallable extends SyntheticCallable {
AndroidComponent targetType;
StartActivitiesSyntheticCallable() {
exists(string id |
this = "android.content.Activity.startActivities()+" + id and
isTargetableType(targetType, id)
)
}
override StartComponentMethodAccess getACall() {
result.getMethod().hasName("startActivities") and
result.targetsComponentType(targetType)
}
override predicate propagatesFlow(
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
) {
exists(ActivityIntentSyntheticGlobal glob | glob.getTargetType() = targetType |
input = SummaryComponentStack::arrayElementOf(SummaryComponentStack::argument(0)) and
output = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(glob)) and
preservesValue = true
)
}
}
private class GetIntentSyntheticCallable extends SyntheticCallable {
AndroidComponent targetType;
GetIntentSyntheticCallable() {
exists(string id |
this = "android.content.Activity.getIntent()+" + id and
isTargetableType(targetType, id)
)
}
override Call getACall() {
result.getCallee() instanceof AndroidGetIntentMethod and
result.getEnclosingCallable().getDeclaringType() = targetType
}
override predicate propagatesFlow(
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
) {
exists(ActivityIntentSyntheticGlobal glob | glob.getTargetType() = targetType |
input = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(glob)) and
output = SummaryComponentStack::return() and
preservesValue = true
)
}
}
private class ActivityIntentSyntheticGlobal extends SummaryComponent::SyntheticGlobal {
AndroidComponent targetType;
ActivityIntentSyntheticGlobal() {
exists(string id |
this = "ActivityIntentSyntheticGlobal+" + id and
isTargetableType(targetType, id)
)
}
AndroidComponent getTargetType() { result = targetType }
}
private class RequiredComponentStackForStartActivities extends RequiredSummaryComponentStack {
override predicate required(SummaryComponent head, SummaryComponentStack tail) {
head = SummaryComponent::arrayElement() and
tail = SummaryComponentStack::argument(0)
}
}
/**
* A value-preserving step from the intent argument of a `sendBroadcast` call to
* the intent parameter in the `onReceive` method of the receiver the

View File

@@ -129,19 +129,20 @@ private predicate isCanonicalTerm(RelevantRegExpTerm term, string str) {
min(RelevantRegExpTerm t, Location loc, File file |
loc = t.getLocation() and
file = t.getFile() and
str = t.getRawValue() + "|" + getCanonicalizationFlags(t.getRootTerm())
str = getCanonicalizationString(t)
|
t order by t.getFile().getRelativePath(), loc.getStartLine(), loc.getStartColumn()
)
}
/**
* Gets a string representation of the flags used with the regular expression.
* Only the flags that are relevant for the canonicalization are included.
* Gets a string representation of `term` that is used for canonicalization.
*/
string getCanonicalizationFlags(RegExpTerm root) {
root.isRootTerm() and
(if RegExpFlags::isIgnoreCase(root) then result = "i" else result = "")
private string getCanonicalizationString(RelevantRegExpTerm term) {
exists(string ignoreCase |
(if RegExpFlags::isIgnoreCase(term.getRootTerm()) then ignoreCase = "i" else ignoreCase = "") and
result = term.getRawValue() + "|" + ignoreCase
)
}
/**
@@ -186,12 +187,19 @@ private newtype TInputSymbol =
Epsilon()
/**
* Gets the canonical CharClass for `term`.
* Gets the the CharClass corresponding to the canonical representative `term`.
*/
CharClass getCanonicalCharClass(RegExpTerm term) {
private CharClass getCharClassForCanonicalTerm(RegExpTerm term) {
exists(string str | isCanonicalTerm(term, str) | result = CharClass(str))
}
/**
* Gets a char class that represents `term`, even when `term` is not the canonical representative.
*/
CharacterClass getCanonicalCharClass(RegExpTerm term) {
exists(string str | str = getCanonicalizationString(term) and result = CharClass(str))
}
/**
* Holds if `a` and `b` are input symbols from the same regexp.
*/
@@ -284,7 +292,7 @@ private module CharacterClasses {
*/
pragma[noinline]
predicate hasChildThatMatchesIgnoringCasingFlags(RegExpCharacterClass cc, string char) {
exists(getCanonicalCharClass(cc)) and
exists(getCharClassForCanonicalTerm(cc)) and
exists(RegExpTerm child | child = cc.getAChild() |
char = child.(RegexpCharacterConstant).getValue()
or
@@ -387,7 +395,7 @@ private module CharacterClasses {
private class PositiveCharacterClass extends CharacterClass {
RegExpCharacterClass cc;
PositiveCharacterClass() { this = getCanonicalCharClass(cc) and not cc.isInverted() }
PositiveCharacterClass() { this = getCharClassForCanonicalTerm(cc) and not cc.isInverted() }
override string getARelevantChar() { result = caseNormalize(getAMentionedChar(cc), cc) }
@@ -400,7 +408,7 @@ private module CharacterClasses {
private class InvertedCharacterClass extends CharacterClass {
RegExpCharacterClass cc;
InvertedCharacterClass() { this = getCanonicalCharClass(cc) and cc.isInverted() }
InvertedCharacterClass() { this = getCharClassForCanonicalTerm(cc) and cc.isInverted() }
override string getARelevantChar() {
result = nextChar(caseNormalize(getAMentionedChar(cc), cc)) or
@@ -435,7 +443,7 @@ private module CharacterClasses {
PositiveCharacterClassEscape() {
isEscapeClass(cc, charClass) and
this = getCanonicalCharClass(cc) and
this = getCharClassForCanonicalTerm(cc) and
charClass = ["d", "s", "w"]
}
@@ -475,7 +483,7 @@ private module CharacterClasses {
NegativeCharacterClassEscape() {
exists(RegExpTerm cc |
isEscapeClass(cc, charClass) and
this = getCanonicalCharClass(cc) and
this = getCharClassForCanonicalTerm(cc) and
charClass = ["D", "S", "W"]
)
}
@@ -652,17 +660,13 @@ predicate delta(State q1, EdgeLabel lbl, State q2) {
cc.isUniversalClass() and q1 = before(cc) and lbl = Any() and q2 = after(cc)
or
q1 = before(cc) and
lbl =
CharacterClasses::normalize(CharClass(cc.getRawValue() + "|" +
getCanonicalizationFlags(cc.getRootTerm()))) and
lbl = CharacterClasses::normalize(CharClass(getCanonicalizationString(cc))) and
q2 = after(cc)
)
or
exists(RegExpTerm cc | isEscapeClass(cc, _) |
q1 = before(cc) and
lbl =
CharacterClasses::normalize(CharClass(cc.getRawValue() + "|" +
getCanonicalizationFlags(cc.getRootTerm()))) and
lbl = CharacterClasses::normalize(CharClass(getCanonicalizationString(cc))) and
q2 = after(cc)
)
or

View File

@@ -26,5 +26,10 @@ where
not exists(getARead(v)) and
// Discarded exceptions are covered by another query.
not exists(CatchClause cc | cc.getVariable().getVariable() = v) and
// Exclude common Kotlin pattern to do something n times: `for(i in 1..n) { doSomething() }
not exists(EnhancedForStmt f |
f.getVariable().getVariable() = v and
f.getExpr().getType().(RefType).hasQualifiedName("kotlin.ranges", ["IntRange", "LongRange"])
) and
not readImplicitly(v)
select v, "Variable '" + v + "' is never read."

View File

@@ -57,6 +57,8 @@ private predicate candidateMethod(RefType t, Method m, string name, int numParam
m.getNumberOfParameters() = numParam and
m = m.getSourceDeclaration() and
not m.getAnAnnotation() instanceof DeprecatedAnnotation and
// Exclude compiler generated methods, such as Kotlin `$default` methods:
not m.isCompilerGenerated() and
not whitelist(name)
}

View File

@@ -1,5 +1,5 @@
name: codeql/java-queries
version: 0.4.3
version: 0.4.4-dev
groups:
- java
- queries

View File

@@ -174,6 +174,8 @@ classes.kt:
# 49| 0: [ClassInstanceExpr] new Enum(...)
# 49| -3: [TypeAccess] Enum<Direction>
# 49| 0: [TypeAccess] Direction
# 49| 0: [NullLiteral] null
# 49| 1: [IntegerLiteral] 0
# 49| 1: [BlockStmt] { ... }
# 50| 5: [FieldDeclaration] Direction NORTH;
# 50| -1: [TypeAccess] Direction
@@ -209,6 +211,8 @@ classes.kt:
# 53| 0: [ClassInstanceExpr] new Enum(...)
# 53| -3: [TypeAccess] Enum<Color>
# 53| 0: [TypeAccess] Color
# 53| 0: [NullLiteral] null
# 53| 1: [IntegerLiteral] 0
# 53| 1: [BlockStmt] { ... }
# 53| 0: [ExprStmt] <Expr>;
# 53| 0: [KtInitializerAssignExpr] ...=...

View File

@@ -3358,6 +3358,8 @@ exprs.kt:
# 174| 0: [ClassInstanceExpr] new Enum(...)
# 174| -3: [TypeAccess] Enum<Direction>
# 174| 0: [TypeAccess] Direction
# 174| 0: [NullLiteral] null
# 174| 1: [IntegerLiteral] 0
# 174| 1: [BlockStmt] { ... }
# 175| 5: [FieldDeclaration] Direction NORTH;
# 175| -1: [TypeAccess] Direction
@@ -3393,6 +3395,8 @@ exprs.kt:
# 178| 0: [ClassInstanceExpr] new Enum(...)
# 178| -3: [TypeAccess] Enum<Color>
# 178| 0: [TypeAccess] Color
# 178| 0: [NullLiteral] null
# 178| 1: [IntegerLiteral] 0
# 178| 1: [BlockStmt] { ... }
# 178| 0: [ExprStmt] <Expr>;
# 178| 0: [KtInitializerAssignExpr] ...=...

View File

@@ -1470,9 +1470,11 @@
| exprs.kt:170:9:170:17 | r2.height | exprs.kt:165:1:172:1 | foo | VarAccess |
| exprs.kt:170:9:170:21 | ...=... | exprs.kt:165:1:172:1 | foo | AssignExpr |
| exprs.kt:170:21:170:21 | 3 | exprs.kt:165:1:172:1 | foo | IntegerLiteral |
| exprs.kt:174:1:176:1 | 0 | exprs.kt:174:6:176:1 | Direction | IntegerLiteral |
| exprs.kt:174:1:176:1 | Direction | exprs.kt:174:6:176:1 | Direction | TypeAccess |
| exprs.kt:174:1:176:1 | Enum<Direction> | exprs.kt:174:6:176:1 | Direction | TypeAccess |
| exprs.kt:174:1:176:1 | new Enum(...) | exprs.kt:174:6:176:1 | Direction | ClassInstanceExpr |
| exprs.kt:174:1:176:1 | null | exprs.kt:174:6:176:1 | Direction | NullLiteral |
| exprs.kt:175:5:175:10 | ...=... | exprs.kt:0:0:0:0 | <clinit> | KtInitializerAssignExpr |
| exprs.kt:175:5:175:10 | Direction | exprs.kt:0:0:0:0 | <clinit> | TypeAccess |
| exprs.kt:175:5:175:10 | Direction | exprs.kt:0:0:0:0 | <clinit> | TypeAccess |
@@ -1497,9 +1499,11 @@
| exprs.kt:175:25:175:28 | Direction | file://:0:0:0:0 | <none> | TypeAccess |
| exprs.kt:175:25:175:28 | Direction.EAST | exprs.kt:0:0:0:0 | <clinit> | VarAccess |
| exprs.kt:175:25:175:28 | new Direction(...) | exprs.kt:0:0:0:0 | <clinit> | ClassInstanceExpr |
| exprs.kt:178:1:182:1 | 0 | exprs.kt:178:6:182:1 | Color | IntegerLiteral |
| exprs.kt:178:1:182:1 | Color | exprs.kt:178:6:182:1 | Color | TypeAccess |
| exprs.kt:178:1:182:1 | Enum<Color> | exprs.kt:178:6:182:1 | Color | TypeAccess |
| exprs.kt:178:1:182:1 | new Enum(...) | exprs.kt:178:6:182:1 | Color | ClassInstanceExpr |
| exprs.kt:178:1:182:1 | null | exprs.kt:178:6:182:1 | Color | NullLiteral |
| exprs.kt:178:18:178:29 | ...=... | exprs.kt:178:6:182:1 | Color | KtInitializerAssignExpr |
| exprs.kt:178:18:178:29 | int | file://:0:0:0:0 | <none> | TypeAccess |
| exprs.kt:178:18:178:29 | int | file://:0:0:0:0 | <none> | TypeAccess |

View File

@@ -88,6 +88,8 @@ A.kt:
# 23| 0: [ClassInstanceExpr] new Enum(...)
# 23| -3: [TypeAccess] Enum<Enu>
# 23| 0: [TypeAccess] Enu
# 23| 0: [NullLiteral] null
# 23| 1: [IntegerLiteral] 0
# 23| 1: [BlockStmt] { ... }
# 24| 5: [FieldDeclaration] Enu A;
# 24| -1: [TypeAccess] Enu

View File

@@ -19,15 +19,16 @@ test.kt:
# 45| 0: [TypeAccess] boolean
# 45| 5: [BlockStmt] { ... }
# 45| 0: [ReturnStmt] return ...
# 45| 0: [MethodAccess] testExtensionFunction(...)
# 45| 0: [MethodAccess] testExtensionFunction$default(...)
# 45| -1: [TypeAccess] TestKt
# 45| 0: [ExtensionReceiverAccess] this
# 45| 1: [VarAccess] a
# 45| 2: [MethodAccess] getString(...)
# 45| -1: [TypeAccess] TestKt
# 45| 3: [VarAccess] c
# 45| 4: [FloatLiteral] 1.0
# 45| 5: [VarAccess] e
# 0| 0: [ExtensionReceiverAccess] this
# 0| 1: [VarAccess] a
# 1| 2: [NullLiteral] null
# 0| 3: [VarAccess] c
# 1| 4: [FloatLiteral] 0.0
# 0| 5: [VarAccess] e
# 1| 6: [IntegerLiteral] 21
# 1| 7: [NullLiteral] null
# 45| 3: [ExtensionMethod] testExtensionFunction
# 45| 3: [TypeAccess] int
#-----| 4: (Parameters)
@@ -43,14 +44,16 @@ test.kt:
# 45| 0: [TypeAccess] boolean
# 45| 5: [BlockStmt] { ... }
# 45| 0: [ReturnStmt] return ...
# 45| 0: [MethodAccess] testExtensionFunction(...)
# 45| 0: [MethodAccess] testExtensionFunction$default(...)
# 45| -1: [TypeAccess] TestKt
# 45| 0: [ExtensionReceiverAccess] this
# 45| 1: [VarAccess] a
# 45| 2: [VarAccess] b
# 45| 3: [VarAccess] c
# 45| 4: [FloatLiteral] 1.0
# 45| 5: [VarAccess] e
# 0| 0: [ExtensionReceiverAccess] this
# 0| 1: [VarAccess] a
# 0| 2: [VarAccess] b
# 0| 3: [VarAccess] c
# 1| 4: [FloatLiteral] 0.0
# 0| 5: [VarAccess] e
# 1| 6: [IntegerLiteral] 23
# 1| 7: [NullLiteral] null
# 45| 4: [ExtensionMethod] testExtensionFunction
# 45| 3: [TypeAccess] int
#-----| 4: (Parameters)
@@ -135,14 +138,15 @@ test.kt:
# 6| 0: [TypeAccess] boolean
# 6| 5: [BlockStmt] { ... }
# 6| 0: [ReturnStmt] return ...
# 6| 0: [MethodAccess] testStaticFunction(...)
# 6| 0: [MethodAccess] testStaticFunction$default(...)
# 6| -1: [TypeAccess] Test
# 6| 0: [VarAccess] a
# 6| 1: [MethodAccess] getString(...)
# 6| -1: [TypeAccess] TestKt
# 6| 2: [VarAccess] c
# 6| 3: [FloatLiteral] 1.0
# 6| 4: [VarAccess] e
# 0| 0: [VarAccess] a
# 1| 1: [NullLiteral] null
# 0| 2: [VarAccess] c
# 1| 3: [FloatLiteral] 0.0
# 0| 4: [VarAccess] e
# 1| 5: [IntegerLiteral] 21
# 1| 6: [NullLiteral] null
# 6| 3: [Method] testStaticFunction
# 6| 3: [TypeAccess] int
#-----| 4: (Parameters)
@@ -156,13 +160,15 @@ test.kt:
# 6| 0: [TypeAccess] boolean
# 6| 5: [BlockStmt] { ... }
# 6| 0: [ReturnStmt] return ...
# 6| 0: [MethodAccess] testStaticFunction(...)
# 6| 0: [MethodAccess] testStaticFunction$default(...)
# 6| -1: [TypeAccess] Test
# 6| 0: [VarAccess] a
# 6| 1: [VarAccess] b
# 6| 2: [VarAccess] c
# 6| 3: [FloatLiteral] 1.0
# 6| 4: [VarAccess] e
# 0| 0: [VarAccess] a
# 0| 1: [VarAccess] b
# 0| 2: [VarAccess] c
# 1| 3: [FloatLiteral] 0.0
# 0| 4: [VarAccess] e
# 1| 5: [IntegerLiteral] 23
# 1| 6: [NullLiteral] null
# 6| 4: [Method] testStaticFunction
# 6| 3: [TypeAccess] int
#-----| 4: (Parameters)
@@ -237,14 +243,16 @@ test.kt:
# 9| 0: [TypeAccess] boolean
# 9| 5: [BlockStmt] { ... }
# 9| 0: [ReturnStmt] return ...
# 9| 0: [MethodAccess] testMemberFunction(...)
# 9| -1: [ThisAccess] this
# 9| 0: [VarAccess] a
# 9| 1: [MethodAccess] getString(...)
# 9| -1: [TypeAccess] TestKt
# 9| 2: [VarAccess] c
# 9| 3: [FloatLiteral] 1.0
# 9| 4: [VarAccess] e
# 9| 0: [MethodAccess] testMemberFunction$default(...)
# 9| -1: [TypeAccess] Test
# 0| 0: [ThisAccess] this
# 0| 1: [VarAccess] a
# 1| 2: [NullLiteral] null
# 0| 3: [VarAccess] c
# 1| 4: [FloatLiteral] 0.0
# 0| 5: [VarAccess] e
# 1| 6: [IntegerLiteral] 21
# 1| 7: [NullLiteral] null
# 9| 7: [Method] testMemberFunction
# 9| 3: [TypeAccess] int
#-----| 4: (Parameters)
@@ -258,13 +266,16 @@ test.kt:
# 9| 0: [TypeAccess] boolean
# 9| 5: [BlockStmt] { ... }
# 9| 0: [ReturnStmt] return ...
# 9| 0: [MethodAccess] testMemberFunction(...)
# 9| -1: [ThisAccess] this
# 9| 0: [VarAccess] a
# 9| 1: [VarAccess] b
# 9| 2: [VarAccess] c
# 9| 3: [FloatLiteral] 1.0
# 9| 4: [VarAccess] e
# 9| 0: [MethodAccess] testMemberFunction$default(...)
# 9| -1: [TypeAccess] Test
# 0| 0: [ThisAccess] this
# 0| 1: [VarAccess] a
# 0| 2: [VarAccess] b
# 0| 3: [VarAccess] c
# 1| 4: [FloatLiteral] 0.0
# 0| 5: [VarAccess] e
# 1| 6: [IntegerLiteral] 23
# 1| 7: [NullLiteral] null
# 9| 8: [Method] testMemberFunction
# 9| 3: [TypeAccess] int
#-----| 4: (Parameters)
@@ -343,15 +354,18 @@ test.kt:
# 12| 0: [TypeAccess] boolean
# 12| 5: [BlockStmt] { ... }
# 12| 0: [ReturnStmt] return ...
# 12| 0: [MethodAccess] testMemberExtensionFunction(...)
# 12| -1: [ThisAccess] this
# 12| 0: [ExtensionReceiverAccess] this
# 12| 1: [VarAccess] a
# 12| 2: [MethodAccess] getString(...)
# 12| -1: [TypeAccess] TestKt
# 12| 3: [VarAccess] c
# 12| 4: [FloatLiteral] 1.0
# 12| 5: [VarAccess] e
# 12| 0: [MethodAccess] testMemberExtensionFunction$default(...)
# 12| -1: [TypeAccess] Test
# 0| 0: [ExtensionReceiverAccess] this
# 0| 1: [ThisAccess] Test.this
# 0| 0: [TypeAccess] Test
# 0| 2: [VarAccess] a
# 1| 3: [NullLiteral] null
# 0| 4: [VarAccess] c
# 1| 5: [FloatLiteral] 0.0
# 0| 6: [VarAccess] e
# 1| 7: [IntegerLiteral] 21
# 1| 8: [NullLiteral] null
# 12| 11: [ExtensionMethod] testMemberExtensionFunction
# 12| 3: [TypeAccess] int
#-----| 4: (Parameters)
@@ -367,14 +381,18 @@ test.kt:
# 12| 0: [TypeAccess] boolean
# 12| 5: [BlockStmt] { ... }
# 12| 0: [ReturnStmt] return ...
# 12| 0: [MethodAccess] testMemberExtensionFunction(...)
# 12| -1: [ThisAccess] this
# 12| 0: [ExtensionReceiverAccess] this
# 12| 1: [VarAccess] a
# 12| 2: [VarAccess] b
# 12| 3: [VarAccess] c
# 12| 4: [FloatLiteral] 1.0
# 12| 5: [VarAccess] e
# 12| 0: [MethodAccess] testMemberExtensionFunction$default(...)
# 12| -1: [TypeAccess] Test
# 0| 0: [ExtensionReceiverAccess] this
# 0| 1: [ThisAccess] Test.this
# 0| 0: [TypeAccess] Test
# 0| 2: [VarAccess] a
# 0| 3: [VarAccess] b
# 0| 4: [VarAccess] c
# 1| 5: [FloatLiteral] 0.0
# 0| 6: [VarAccess] e
# 1| 7: [IntegerLiteral] 23
# 1| 8: [NullLiteral] null
# 12| 12: [ExtensionMethod] testMemberExtensionFunction
# 12| 3: [TypeAccess] int
#-----| 4: (Parameters)
@@ -456,12 +474,13 @@ test.kt:
# 16| 0: [TypeAccess] boolean
# 16| 5: [BlockStmt] { ... }
# 16| 0: [ThisConstructorInvocationStmt] this(...)
# 16| 0: [VarAccess] a
# 16| 1: [MethodAccess] getString(...)
# 16| -1: [TypeAccess] TestKt
# 16| 2: [VarAccess] c
# 16| 3: [FloatLiteral] 1.0
# 16| 4: [VarAccess] e
# 0| 0: [VarAccess] a
# 1| 1: [NullLiteral] null
# 0| 2: [VarAccess] c
# 1| 3: [FloatLiteral] 0.0
# 0| 4: [VarAccess] e
# 1| 5: [IntegerLiteral] 21
# 1| 6: [NullLiteral] null
# 16| 2: [Constructor] Test2
#-----| 4: (Parameters)
# 16| 0: [Parameter] a
@@ -474,11 +493,13 @@ test.kt:
# 16| 0: [TypeAccess] boolean
# 16| 5: [BlockStmt] { ... }
# 16| 0: [ThisConstructorInvocationStmt] this(...)
# 16| 0: [VarAccess] a
# 16| 1: [VarAccess] b
# 16| 2: [VarAccess] c
# 16| 3: [FloatLiteral] 1.0
# 16| 4: [VarAccess] e
# 0| 0: [VarAccess] a
# 0| 1: [VarAccess] b
# 0| 2: [VarAccess] c
# 1| 3: [FloatLiteral] 0.0
# 0| 4: [VarAccess] e
# 1| 5: [IntegerLiteral] 23
# 1| 6: [NullLiteral] null
# 16| 3: [Constructor] Test2
#-----| 4: (Parameters)
# 16| 0: [Parameter] a
@@ -554,14 +575,16 @@ test.kt:
# 21| 0: [TypeAccess] boolean
# 21| 5: [BlockStmt] { ... }
# 21| 0: [ReturnStmt] return ...
# 21| 0: [MethodAccess] testCompanionFunction(...)
# 21| -1: [ThisAccess] this
# 21| 0: [VarAccess] a
# 21| 1: [MethodAccess] getString(...)
# 21| -1: [TypeAccess] TestKt
# 21| 2: [VarAccess] c
# 21| 3: [FloatLiteral] 1.0
# 21| 4: [VarAccess] e
# 21| 0: [MethodAccess] testCompanionFunction$default(...)
# 21| -1: [TypeAccess] Companion
# 0| 0: [ThisAccess] this
# 0| 1: [VarAccess] a
# 1| 2: [NullLiteral] null
# 0| 3: [VarAccess] c
# 1| 4: [FloatLiteral] 0.0
# 0| 5: [VarAccess] e
# 1| 6: [IntegerLiteral] 21
# 1| 7: [NullLiteral] null
# 21| 3: [Method] testCompanionFunction
# 21| 3: [TypeAccess] int
#-----| 4: (Parameters)
@@ -575,13 +598,16 @@ test.kt:
# 21| 0: [TypeAccess] boolean
# 21| 5: [BlockStmt] { ... }
# 21| 0: [ReturnStmt] return ...
# 21| 0: [MethodAccess] testCompanionFunction(...)
# 21| -1: [ThisAccess] this
# 21| 0: [VarAccess] a
# 21| 1: [VarAccess] b
# 21| 2: [VarAccess] c
# 21| 3: [FloatLiteral] 1.0
# 21| 4: [VarAccess] e
# 21| 0: [MethodAccess] testCompanionFunction$default(...)
# 21| -1: [TypeAccess] Companion
# 0| 0: [ThisAccess] this
# 0| 1: [VarAccess] a
# 0| 2: [VarAccess] b
# 0| 3: [VarAccess] c
# 1| 4: [FloatLiteral] 0.0
# 0| 5: [VarAccess] e
# 1| 6: [IntegerLiteral] 23
# 1| 7: [NullLiteral] null
# 21| 4: [Method] testCompanionFunction
# 21| 3: [TypeAccess] int
#-----| 4: (Parameters)
@@ -658,14 +684,16 @@ test.kt:
# 24| 0: [TypeAccess] boolean
# 24| 5: [BlockStmt] { ... }
# 24| 0: [ReturnStmt] return ...
# 24| 0: [MethodAccess] testStaticCompanionFunction(...)
# 24| -1: [ThisAccess] this
# 24| 0: [VarAccess] a
# 24| 1: [MethodAccess] getString(...)
# 24| -1: [TypeAccess] TestKt
# 24| 2: [VarAccess] c
# 24| 3: [FloatLiteral] 1.0
# 24| 4: [VarAccess] e
# 24| 0: [MethodAccess] testStaticCompanionFunction$default(...)
# 24| -1: [TypeAccess] Companion
# 0| 0: [ThisAccess] this
# 0| 1: [VarAccess] a
# 1| 2: [NullLiteral] null
# 0| 3: [VarAccess] c
# 1| 4: [FloatLiteral] 0.0
# 0| 5: [VarAccess] e
# 1| 6: [IntegerLiteral] 21
# 1| 7: [NullLiteral] null
# 24| 7: [Method] testStaticCompanionFunction
# 24| 3: [TypeAccess] int
#-----| 4: (Parameters)
@@ -679,13 +707,16 @@ test.kt:
# 24| 0: [TypeAccess] boolean
# 24| 5: [BlockStmt] { ... }
# 24| 0: [ReturnStmt] return ...
# 24| 0: [MethodAccess] testStaticCompanionFunction(...)
# 24| -1: [ThisAccess] this
# 24| 0: [VarAccess] a
# 24| 1: [VarAccess] b
# 24| 2: [VarAccess] c
# 24| 3: [FloatLiteral] 1.0
# 24| 4: [VarAccess] e
# 24| 0: [MethodAccess] testStaticCompanionFunction$default(...)
# 24| -1: [TypeAccess] Companion
# 0| 0: [ThisAccess] this
# 0| 1: [VarAccess] a
# 0| 2: [VarAccess] b
# 0| 3: [VarAccess] c
# 1| 4: [FloatLiteral] 0.0
# 0| 5: [VarAccess] e
# 1| 6: [IntegerLiteral] 23
# 1| 7: [NullLiteral] null
# 24| 8: [Method] testStaticCompanionFunction
# 24| 3: [TypeAccess] int
#-----| 4: (Parameters)
@@ -762,14 +793,16 @@ test.kt:
# 24| 0: [TypeAccess] boolean
# 24| 5: [BlockStmt] { ... }
# 24| 0: [ReturnStmt] return ...
# 24| 0: [MethodAccess] testStaticCompanionFunction(...)
# 24| -1: [ThisAccess] this
# 24| 0: [VarAccess] a
# 24| 1: [MethodAccess] getString(...)
# 24| -1: [TypeAccess] TestKt
# 24| 2: [VarAccess] c
# 24| 3: [FloatLiteral] 1.0
# 24| 4: [VarAccess] e
# 24| 0: [MethodAccess] testStaticCompanionFunction$default(...)
# 24| -1: [TypeAccess] Companion
# 0| 0: [ThisAccess] this
# 0| 1: [VarAccess] a
# 1| 2: [NullLiteral] null
# 0| 3: [VarAccess] c
# 1| 4: [FloatLiteral] 0.0
# 0| 5: [VarAccess] e
# 1| 6: [IntegerLiteral] 21
# 1| 7: [NullLiteral] null
# 24| 7: [Method] testStaticCompanionFunction
# 24| 3: [TypeAccess] int
#-----| 4: (Parameters)
@@ -783,13 +816,16 @@ test.kt:
# 24| 0: [TypeAccess] boolean
# 24| 5: [BlockStmt] { ... }
# 24| 0: [ReturnStmt] return ...
# 24| 0: [MethodAccess] testStaticCompanionFunction(...)
# 24| -1: [ThisAccess] this
# 24| 0: [VarAccess] a
# 24| 1: [VarAccess] b
# 24| 2: [VarAccess] c
# 24| 3: [FloatLiteral] 1.0
# 24| 4: [VarAccess] e
# 24| 0: [MethodAccess] testStaticCompanionFunction$default(...)
# 24| -1: [TypeAccess] Companion
# 0| 0: [ThisAccess] this
# 0| 1: [VarAccess] a
# 0| 2: [VarAccess] b
# 0| 3: [VarAccess] c
# 1| 4: [FloatLiteral] 0.0
# 0| 5: [VarAccess] e
# 1| 6: [IntegerLiteral] 23
# 1| 7: [NullLiteral] null
# 24| 8: [Method] testStaticCompanionFunction
# 24| 3: [TypeAccess] int
#-----| 4: (Parameters)
@@ -824,10 +860,12 @@ test.kt:
# 30| 0: [TypeAccess] T
# 30| 5: [BlockStmt] { ... }
# 30| 0: [ThisConstructorInvocationStmt] this(...)
# 30| 0: [IntegerLiteral] 1
# 30| 1: [VarAccess] b
# 30| 2: [StringLiteral] Hello world
# 30| 3: [VarAccess] d
# 1| 0: [IntegerLiteral] 0
# 0| 1: [VarAccess] b
# 1| 2: [NullLiteral] null
# 0| 3: [VarAccess] d
# 1| 4: [IntegerLiteral] 10
# 1| 5: [NullLiteral] null
# 30| 2: [Constructor] GenericTest
#-----| 4: (Parameters)
# 30| 0: [Parameter] a
@@ -838,10 +876,12 @@ test.kt:
# 30| 0: [TypeAccess] T
# 30| 5: [BlockStmt] { ... }
# 30| 0: [ThisConstructorInvocationStmt] this(...)
# 30| 0: [VarAccess] a
# 30| 1: [VarAccess] b
# 30| 2: [StringLiteral] Hello world
# 30| 3: [VarAccess] d
# 0| 0: [VarAccess] a
# 0| 1: [VarAccess] b
# 1| 2: [NullLiteral] null
# 0| 3: [VarAccess] d
# 1| 4: [IntegerLiteral] 11
# 1| 5: [NullLiteral] null
# 30| 3: [Constructor] GenericTest
#-----| 4: (Parameters)
# 30| 0: [Parameter] a
@@ -904,12 +944,15 @@ test.kt:
# 33| 0: [TypeAccess] T
# 33| 5: [BlockStmt] { ... }
# 33| 0: [ReturnStmt] return ...
# 33| 0: [MethodAccess] testMemberFunction(...)
# 33| -1: [ThisAccess] this
# 33| 0: [IntegerLiteral] 1
# 33| 1: [VarAccess] b
# 33| 2: [StringLiteral] Hello world
# 33| 3: [VarAccess] d
# 33| 0: [MethodAccess] testMemberFunction$default(...)
# 33| -1: [TypeAccess] GenericTest<>
# 0| 0: [ThisAccess] this
# 1| 1: [IntegerLiteral] 0
# 0| 2: [VarAccess] b
# 1| 3: [NullLiteral] null
# 0| 4: [VarAccess] d
# 1| 5: [IntegerLiteral] 10
# 1| 6: [NullLiteral] null
# 33| 6: [Method] testMemberFunction
# 33| 3: [TypeAccess] int
#-----| 4: (Parameters)
@@ -921,12 +964,15 @@ test.kt:
# 33| 0: [TypeAccess] T
# 33| 5: [BlockStmt] { ... }
# 33| 0: [ReturnStmt] return ...
# 33| 0: [MethodAccess] testMemberFunction(...)
# 33| -1: [ThisAccess] this
# 33| 0: [VarAccess] a
# 33| 1: [VarAccess] b
# 33| 2: [StringLiteral] Hello world
# 33| 3: [VarAccess] d
# 33| 0: [MethodAccess] testMemberFunction$default(...)
# 33| -1: [TypeAccess] GenericTest<>
# 0| 0: [ThisAccess] this
# 0| 1: [VarAccess] a
# 0| 2: [VarAccess] b
# 1| 3: [NullLiteral] null
# 0| 4: [VarAccess] d
# 1| 5: [IntegerLiteral] 11
# 1| 6: [NullLiteral] null
# 33| 7: [Method] testMemberFunction
# 33| 3: [TypeAccess] int
#-----| 4: (Parameters)

View File

@@ -12,16 +12,9 @@
| User.java:35:61:35:68 | source(...) | test.kt:74:10:74:10 | s | User.java:5:22:5:25 | test |
| User.java:38:28:38:35 | source(...) | test.kt:84:10:84:10 | y | User.java:5:22:5:25 | test |
| User.java:39:20:39:27 | source(...) | test.kt:84:10:84:10 | y | User.java:5:22:5:25 | test |
| test.kt:10:55:10:62 | source(...) | test.kt:10:84:10:84 | s | test.kt:10:3:10:87 | taintSuppliedAsDefault |
| test.kt:10:55:10:62 | source(...) | test.kt:10:84:10:84 | s | test.kt:10:3:10:87 | taintSuppliedAsDefault$default |
| test.kt:22:63:22:70 | source(...) | test.kt:22:92:22:92 | s | test.kt:22:5:22:95 | taintSuppliedAsDefaultStatic |
| test.kt:22:63:22:70 | source(...) | test.kt:22:92:22:92 | s | test.kt:22:5:22:95 | taintSuppliedAsDefaultStatic |
| test.kt:22:63:22:70 | source(...) | test.kt:22:92:22:92 | s | test.kt:22:5:22:95 | taintSuppliedAsDefaultStatic$default |
| test.kt:30:55:30:62 | source(...) | test.kt:30:84:30:84 | s | test.kt:30:3:30:87 | taintSuppliedAsDefault |
| test.kt:30:55:30:62 | source(...) | test.kt:30:84:30:84 | s | test.kt:30:3:30:87 | taintSuppliedAsDefault$default |
| test.kt:40:53:40:60 | source(...) | test.kt:40:80:40:80 | s | test.kt:40:3:40:83 | taintSuppliedAsDefault |
| test.kt:40:53:40:60 | source(...) | test.kt:40:80:40:80 | s | test.kt:40:3:40:83 | taintSuppliedAsDefault$default |
| test.kt:47:92:47:99 | source(...) | test.kt:50:10:50:10 | s | test.kt:47:55:53:1 | ConstructorTaintsByDefault |
| test.kt:47:92:47:99 | source(...) | test.kt:50:10:50:10 | s | test.kt:47:55:53:1 | ConstructorTaintsByDefault |
| test.kt:63:100:63:107 | source(...) | test.kt:66:10:66:10 | s | test.kt:63:65:69:1 | GenericConstructorTaintsByDefault |
| test.kt:63:100:63:107 | source(...) | test.kt:66:10:66:10 | s | test.kt:63:65:69:1 | GenericConstructorTaintsByDefault |

View File

@@ -231,9 +231,11 @@
| enumClass.kt:0:0:0:0 | EnumWithFunctions[] | TypeAccess |
| enumClass.kt:0:0:0:0 | String | TypeAccess |
| enumClass.kt:0:0:0:0 | String | TypeAccess |
| enumClass.kt:1:1:4:1 | 0 | IntegerLiteral |
| enumClass.kt:1:1:4:1 | Enum<EnumClass> | TypeAccess |
| enumClass.kt:1:1:4:1 | EnumClass | TypeAccess |
| enumClass.kt:1:1:4:1 | new Enum(...) | ClassInstanceExpr |
| enumClass.kt:1:1:4:1 | null | NullLiteral |
| enumClass.kt:1:22:1:31 | ...=... | KtInitializerAssignExpr |
| enumClass.kt:1:22:1:31 | int | TypeAccess |
| enumClass.kt:1:22:1:31 | int | TypeAccess |
@@ -256,9 +258,11 @@
| enumClass.kt:3:5:3:12 | EnumClass.enum2 | VarAccess |
| enumClass.kt:3:5:3:12 | new EnumClass(...) | ClassInstanceExpr |
| enumClass.kt:3:11:3:11 | 1 | IntegerLiteral |
| enumClass.kt:6:1:16:1 | 0 | IntegerLiteral |
| enumClass.kt:6:1:16:1 | Enum<EnumWithFunctions> | TypeAccess |
| enumClass.kt:6:1:16:1 | EnumWithFunctions | TypeAccess |
| enumClass.kt:6:1:16:1 | new Enum(...) | ClassInstanceExpr |
| enumClass.kt:6:1:16:1 | null | NullLiteral |
| enumClass.kt:8:3:11:4 | ...=... | KtInitializerAssignExpr |
| enumClass.kt:8:3:11:4 | <implicit coercion to unit> | ImplicitCoercionToUnitExpr |
| enumClass.kt:8:3:11:4 | EnumWithFunctions | TypeAccess |

View File

@@ -7,3 +7,8 @@ class C {
prop(this)
}
}
class A {
fun <T : Any> fn(value: T, i: Int = 1) {}
fun fn(value: String, i: Int = 1) {}
}

View File

@@ -0,0 +1,3 @@
| test.kt:8:10:8:10 | int e | Variable 'int e' is never read. |
| test.kt:14:11:14:13 | int idx | Variable 'int idx' is never read. |
| test.kt:14:16:14:16 | int e | Variable 'int e' is never read. |

View File

@@ -0,0 +1 @@
Violations of Best Practice/Dead Code/UnreadLocal.ql

View File

@@ -0,0 +1,25 @@
fun fn0(size: Int) {
for (idx in 1..size) {
println()
}
}
fun fn1(a: Array<Int>) {
for (e in a) {
println()
}
}
fun fn2(a: Array<Int>) {
for ((idx, e) in a.withIndex()) {
println()
}
}
fun fn3() {
for (i in 1 until 10) {
println()
}
}
// Diagnostic Matches: % Couldn't find a Java equivalent function to kotlin.Int.rangeTo in java.lang.Integer%

View File

@@ -24,6 +24,12 @@ public class TestStartActivityToGetIntent {
Intent[] intents = new Intent[] {intent};
ctx.startActivities(intents);
}
{
Intent intent = new Intent(null, AnotherActivity.class);
intent.putExtra("data", (String) source("ctx-start-acts-2"));
Intent[] intents = new Intent[] {intent};
ctx.startActivities(intents);
}
{
Intent intent = new Intent(null, SomeActivity.class);
intent.putExtra("data", (String) source("act-start"));
@@ -35,6 +41,12 @@ public class TestStartActivityToGetIntent {
Intent[] intents = new Intent[] {intent};
act.startActivities(intents);
}
{
Intent intent = new Intent(null, Object.class);
intent.putExtra("data", (String) source("start-activities-should-not-reach"));
Intent[] intents = new Intent[] {intent};
act.startActivities(intents);
}
{
Intent intent = new Intent(null, SomeActivity.class);
intent.putExtra("data", (String) source("start-for-result"));
@@ -79,9 +91,16 @@ public class TestStartActivityToGetIntent {
static class SomeActivity extends Activity {
public void test() {
sink(getIntent().getStringExtra("data")); // $ hasValueFlow=ctx-start hasValueFlow=act-start hasValueFlow=start-for-result hasValueFlow=start-if-needed hasValueFlow=start-matching hasValueFlow=start-from-child hasValueFlow=start-from-frag hasValueFlow=4-arg MISSING: hasValueFlow=ctx-start-acts hasValueFlow=act-start-acts
// @formatter:off
sink(getIntent().getStringExtra("data")); // $ hasValueFlow=ctx-start hasValueFlow=act-start hasValueFlow=start-for-result hasValueFlow=start-if-needed hasValueFlow=start-matching hasValueFlow=start-from-child hasValueFlow=start-from-frag hasValueFlow=4-arg hasValueFlow=ctx-start-acts hasValueFlow=act-start-acts
// @formatter:on
}
}
static class AnotherActivity extends Activity {
public void test() {
sink(getIntent().getStringExtra("data")); // $ hasValueFlow=ctx-start-acts-2
}
}
static class SafeActivity extends Activity {

View File

@@ -0,0 +1,19 @@
public class Test {
static class BoundedGeneric<T extends CharSequence> {
public T getter(int unused) { return null; }
public void setter(T t) { }
}
public static BoundedGeneric<?> getUnbounded() { return null; }
public static BoundedGeneric<? super String> getLowerBounded() { return null; }
public static void test() {
CharSequence cs = getUnbounded().getter(0);
Object o = getLowerBounded().getter(0);
getUnbounded().setter(null);
getLowerBounded().setter(null);
}
}

View File

@@ -0,0 +1,4 @@
| Test$BoundedGeneric.class:0:0:0:0 | getter | Test$BoundedGeneric.class:0:0:0:0 | BoundedGeneric<? super String> | CharSequence | int |
| Test$BoundedGeneric.class:0:0:0:0 | getter | Test$BoundedGeneric.class:0:0:0:0 | BoundedGeneric<?> | CharSequence | int |
| Test$BoundedGeneric.class:0:0:0:0 | setter | Test$BoundedGeneric.class:0:0:0:0 | BoundedGeneric<? super String> | void | String |
| Test$BoundedGeneric.class:0:0:0:0 | setter | Test$BoundedGeneric.class:0:0:0:0 | BoundedGeneric<?> | void | <nulltype> |

View File

@@ -0,0 +1,5 @@
import java
from MethodAccess ma
select ma.getCallee(), ma.getCallee().getDeclaringType(), ma.getCallee().getReturnType().toString(),
ma.getCallee().getAParamType().toString()

View File

@@ -0,0 +1,13 @@
import java.util.Collection;
public class Test {
public Collection<? extends CharSequence> getCollection() {
return null;
}
public void test() {
this.getCollection().isEmpty();
}
}

View File

@@ -0,0 +1,5 @@
import java
from Method m, Type t
where m.getAParamType() = t and t.toString().matches("%? super ? extends%")
select m, t

View File

@@ -6,6 +6,7 @@
private import javascript as JS
import EndpointTypes
import EndpointCharacteristics
/**
* EXPERIMENTAL. This API may change in the future.
@@ -44,7 +45,14 @@ abstract class AtmConfig extends string {
*
* Holds if `sink` is a known sink of flow.
*/
predicate isKnownSink(JS::DataFlow::Node sink) { none() }
final predicate isKnownSink(JS::DataFlow::Node sink) {
// If the list of characteristics includes positive indicators with maximal confidence for this class, then it's a
// known sink for the class.
exists(EndpointCharacteristic characteristic |
characteristic.getEndpoints(sink) and
characteristic.getImplications(this.getASinkEndpointType(), true, 1.0)
)
}
/**
* EXPERIMENTAL. This API may change in the future.

View File

@@ -0,0 +1,110 @@
/**
* For internal use only.
*/
import experimental.adaptivethreatmodeling.EndpointTypes
private import semmle.javascript.security.dataflow.SqlInjectionCustomizations
private import semmle.javascript.security.dataflow.DomBasedXssCustomizations
private import semmle.javascript.security.dataflow.NosqlInjectionCustomizations
private import semmle.javascript.security.dataflow.TaintedPathCustomizations
/**
* A set of characteristics that a particular endpoint might have. This set of characteristics is used to make decisions
* about whether to include the endpoint in the training set and with what label, as well as whether to score the
* endpoint at inference time.
*/
abstract class EndpointCharacteristic extends string {
/**
* Holds when the string matches the name of the characteristic, which should describe some characteristic of the
* endpoint that is meaningful for determining whether it's a sink and if so of which type
*/
bindingset[this]
EndpointCharacteristic() { any() }
/**
* Holds for endpoints that have this characteristic. This predicate contains the logic that applies characteristics
* to the appropriate set of dataflow nodes.
*/
abstract predicate getEndpoints(DataFlow::Node n);
/**
* This predicate describes what the characteristic tells us about an endpoint.
*
* Params:
* endpointClass: Class 0 is the negative class. Each positive int corresponds to a single sink type.
* isPositiveIndicator: Does this characteristic indicate this endpoint _is_ a member of the class, or that it
* _isn't_ a member of the class?
* confidence: A number in [0, 1], which tells us how strong an indicator this characteristic is for the endpoint
* belonging / not belonging to the given class.
*/
abstract predicate getImplications(
EndpointType endpointClass, boolean isPositiveIndicator, float confidence
);
}
/**
* Endpoints identified as "DomBasedXssSink" by the standard JavaScript libraries are XSS sinks with maximal confidence.
*/
private class DomBasedXssSinkCharacteristic extends EndpointCharacteristic {
DomBasedXssSinkCharacteristic() { this = "DomBasedXssSink" }
override predicate getEndpoints(DataFlow::Node n) { n instanceof DomBasedXss::Sink }
override predicate getImplications(
EndpointType endpointClass, boolean isPositiveIndicator, float confidence
) {
endpointClass instanceof XssSinkType and isPositiveIndicator = true and confidence = 1.0
}
}
/**
* Endpoints identified as "TaintedPathSink" by the standard JavaScript libraries are path injection sinks with maximal
* confidence.
*/
private class TaintedPathSinkCharacteristic extends EndpointCharacteristic {
TaintedPathSinkCharacteristic() { this = "TaintedPathSink" }
override predicate getEndpoints(DataFlow::Node n) { n instanceof TaintedPath::Sink }
override predicate getImplications(
EndpointType endpointClass, boolean isPositiveIndicator, float confidence
) {
endpointClass instanceof TaintedPathSinkType and isPositiveIndicator = true and confidence = 1.0
}
}
/**
* Endpoints identified as "SqlInjectionSink" by the standard JavaScript libraries are SQL injection sinks with maximal
* confidence.
*/
private class SqlInjectionSinkCharacteristic extends EndpointCharacteristic {
SqlInjectionSinkCharacteristic() { this = "SqlInjectionSink" }
override predicate getEndpoints(DataFlow::Node n) { n instanceof SqlInjection::Sink }
override predicate getImplications(
EndpointType endpointClass, boolean isPositiveIndicator, float confidence
) {
endpointClass instanceof SqlInjectionSinkType and
isPositiveIndicator = true and
confidence = 1.0
}
}
/**
* Endpoints identified as "NosqlInjectionSink" by the standard JavaScript libraries are NoSQL injection sinks with
* maximal confidence.
*/
private class NosqlInjectionSinkCharacteristic extends EndpointCharacteristic {
NosqlInjectionSinkCharacteristic() { this = "NosqlInjectionSink" }
override predicate getEndpoints(DataFlow::Node n) { n instanceof NosqlInjection::Sink }
override predicate getImplications(
EndpointType endpointClass, boolean isPositiveIndicator, float confidence
) {
endpointClass instanceof NosqlInjectionSinkType and
isPositiveIndicator = true and
confidence = 1.0
}
}

View File

@@ -93,8 +93,6 @@ class NosqlInjectionAtmConfig extends AtmConfig {
source instanceof NosqlInjection::Source or TaintedObject::isSource(source, _)
}
override predicate isKnownSink(DataFlow::Node sink) { sink instanceof NosqlInjection::Sink }
override predicate isEffectiveSink(DataFlow::Node sinkCandidate) {
not exists(SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate))
}

View File

@@ -65,8 +65,6 @@ class SqlInjectionAtmConfig extends AtmConfig {
override predicate isKnownSource(DataFlow::Node source) { source instanceof SqlInjection::Source }
override predicate isKnownSink(DataFlow::Node sink) { sink instanceof SqlInjection::Sink }
override predicate isEffectiveSink(DataFlow::Node sinkCandidate) {
not exists(SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate))
}

View File

@@ -64,8 +64,6 @@ class TaintedPathAtmConfig extends AtmConfig {
override predicate isKnownSource(DataFlow::Node source) { source instanceof TaintedPath::Source }
override predicate isKnownSink(DataFlow::Node sink) { sink instanceof TaintedPath::Sink }
override predicate isEffectiveSink(DataFlow::Node sinkCandidate) {
not exists(SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate))
}

View File

@@ -65,8 +65,6 @@ class DomBasedXssAtmConfig extends AtmConfig {
override predicate isKnownSource(DataFlow::Node source) { source instanceof DomBasedXss::Source }
override predicate isKnownSink(DataFlow::Node sink) { sink instanceof DomBasedXss::Sink }
override predicate isEffectiveSink(DataFlow::Node sinkCandidate) {
not exists(SinkEndpointFilter::getAReasonSinkExcluded(sinkCandidate))
}

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-experimental-atm-lib
version: 0.3.7
version: 0.4.1
extractor: javascript
library: true
groups:

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-experimental-atm-model
version: 0.2.1
version: 0.3.1
groups:
- javascript
- experimental

View File

@@ -1,6 +1,6 @@
---
dependencies:
codeql/javascript-experimental-atm-model:
version: 0.2.1-2022-09-06-08h55m54s.bubbly-basin-xpztl8fh.f3c3c9360a727959e428ecc6932257e6a546dc65d8a9baac525a49247123822d
version: 0.3.0
compiled: false
lockVersion: 1.0.0

View File

@@ -6,4 +6,4 @@ groups:
- experimental
dependencies:
codeql/javascript-experimental-atm-lib: ${workspace}
codeql/javascript-experimental-atm-model: "0.2.1-2022-09-06-08h55m54s.bubbly-basin-xpztl8fh.f3c3c9360a727959e428ecc6932257e6a546dc65d8a9baac525a49247123822d"
codeql/javascript-experimental-atm-model: "0.3.0"

View File

@@ -1,6 +1,6 @@
---
dependencies:
codeql/javascript-experimental-atm-model:
version: 0.2.1-2022-09-06-08h55m54s.bubbly-basin-xpztl8fh.f3c3c9360a727959e428ecc6932257e6a546dc65d8a9baac525a49247123822d
version: 0.3.0
compiled: false
lockVersion: 1.0.0

View File

@@ -1,6 +1,6 @@
name: codeql/javascript-experimental-atm-queries
language: javascript
version: 0.3.7
version: 0.4.1
suites: codeql-suites
defaultSuiteFile: codeql-suites/javascript-atm-code-scanning.qls
groups:
@@ -8,4 +8,4 @@ groups:
- experimental
dependencies:
codeql/javascript-experimental-atm-lib: ${workspace}
codeql/javascript-experimental-atm-model: "0.2.1-2022-09-06-08h55m54s.bubbly-basin-xpztl8fh.f3c3c9360a727959e428ecc6932257e6a546dc65d8a9baac525a49247123822d"
codeql/javascript-experimental-atm-model: "0.3.0"

View File

@@ -1,6 +1,6 @@
---
dependencies:
codeql/javascript-experimental-atm-model:
version: 0.2.1-2022-09-06-08h55m54s.bubbly-basin-xpztl8fh.f3c3c9360a727959e428ecc6932257e6a546dc65d8a9baac525a49247123822d
version: 0.3.0
compiled: false
lockVersion: 1.0.0

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-all
version: 0.3.3
version: 0.3.4-dev
groups: javascript
dbscheme: semmlecode.javascript.dbscheme
extractor: javascript

View File

@@ -129,19 +129,20 @@ private predicate isCanonicalTerm(RelevantRegExpTerm term, string str) {
min(RelevantRegExpTerm t, Location loc, File file |
loc = t.getLocation() and
file = t.getFile() and
str = t.getRawValue() + "|" + getCanonicalizationFlags(t.getRootTerm())
str = getCanonicalizationString(t)
|
t order by t.getFile().getRelativePath(), loc.getStartLine(), loc.getStartColumn()
)
}
/**
* Gets a string representation of the flags used with the regular expression.
* Only the flags that are relevant for the canonicalization are included.
* Gets a string representation of `term` that is used for canonicalization.
*/
string getCanonicalizationFlags(RegExpTerm root) {
root.isRootTerm() and
(if RegExpFlags::isIgnoreCase(root) then result = "i" else result = "")
private string getCanonicalizationString(RelevantRegExpTerm term) {
exists(string ignoreCase |
(if RegExpFlags::isIgnoreCase(term.getRootTerm()) then ignoreCase = "i" else ignoreCase = "") and
result = term.getRawValue() + "|" + ignoreCase
)
}
/**
@@ -186,12 +187,19 @@ private newtype TInputSymbol =
Epsilon()
/**
* Gets the canonical CharClass for `term`.
* Gets the the CharClass corresponding to the canonical representative `term`.
*/
CharClass getCanonicalCharClass(RegExpTerm term) {
private CharClass getCharClassForCanonicalTerm(RegExpTerm term) {
exists(string str | isCanonicalTerm(term, str) | result = CharClass(str))
}
/**
* Gets a char class that represents `term`, even when `term` is not the canonical representative.
*/
CharacterClass getCanonicalCharClass(RegExpTerm term) {
exists(string str | str = getCanonicalizationString(term) and result = CharClass(str))
}
/**
* Holds if `a` and `b` are input symbols from the same regexp.
*/
@@ -284,7 +292,7 @@ private module CharacterClasses {
*/
pragma[noinline]
predicate hasChildThatMatchesIgnoringCasingFlags(RegExpCharacterClass cc, string char) {
exists(getCanonicalCharClass(cc)) and
exists(getCharClassForCanonicalTerm(cc)) and
exists(RegExpTerm child | child = cc.getAChild() |
char = child.(RegexpCharacterConstant).getValue()
or
@@ -387,7 +395,7 @@ private module CharacterClasses {
private class PositiveCharacterClass extends CharacterClass {
RegExpCharacterClass cc;
PositiveCharacterClass() { this = getCanonicalCharClass(cc) and not cc.isInverted() }
PositiveCharacterClass() { this = getCharClassForCanonicalTerm(cc) and not cc.isInverted() }
override string getARelevantChar() { result = caseNormalize(getAMentionedChar(cc), cc) }
@@ -400,7 +408,7 @@ private module CharacterClasses {
private class InvertedCharacterClass extends CharacterClass {
RegExpCharacterClass cc;
InvertedCharacterClass() { this = getCanonicalCharClass(cc) and cc.isInverted() }
InvertedCharacterClass() { this = getCharClassForCanonicalTerm(cc) and cc.isInverted() }
override string getARelevantChar() {
result = nextChar(caseNormalize(getAMentionedChar(cc), cc)) or
@@ -435,7 +443,7 @@ private module CharacterClasses {
PositiveCharacterClassEscape() {
isEscapeClass(cc, charClass) and
this = getCanonicalCharClass(cc) and
this = getCharClassForCanonicalTerm(cc) and
charClass = ["d", "s", "w"]
}
@@ -475,7 +483,7 @@ private module CharacterClasses {
NegativeCharacterClassEscape() {
exists(RegExpTerm cc |
isEscapeClass(cc, charClass) and
this = getCanonicalCharClass(cc) and
this = getCharClassForCanonicalTerm(cc) and
charClass = ["D", "S", "W"]
)
}
@@ -652,17 +660,13 @@ predicate delta(State q1, EdgeLabel lbl, State q2) {
cc.isUniversalClass() and q1 = before(cc) and lbl = Any() and q2 = after(cc)
or
q1 = before(cc) and
lbl =
CharacterClasses::normalize(CharClass(cc.getRawValue() + "|" +
getCanonicalizationFlags(cc.getRootTerm()))) and
lbl = CharacterClasses::normalize(CharClass(getCanonicalizationString(cc))) and
q2 = after(cc)
)
or
exists(RegExpTerm cc | isEscapeClass(cc, _) |
q1 = before(cc) and
lbl =
CharacterClasses::normalize(CharClass(cc.getRawValue() + "|" +
getCanonicalizationFlags(cc.getRootTerm()))) and
lbl = CharacterClasses::normalize(CharClass(getCanonicalizationString(cc))) and
q2 = after(cc)
)
or

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-queries
version: 0.4.3
version: 0.4.4-dev
groups:
- javascript
- queries

View File

@@ -37,3 +37,5 @@
| tst-multi-character-sanitization.js:143:13:143:56 | content ... /g, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:143:30:143:30 | < | <script |
| tst-multi-character-sanitization.js:144:13:144:91 | content ... /g, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:144:30:144:30 | < | <script |
| tst-multi-character-sanitization.js:145:13:145:90 | content ... /g, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:145:30:145:30 | < | <script |
| tst-multi-character-sanitization.js:148:3:148:99 | n.clone ... gi, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:148:41:148:41 | < | <script |
| tst-multi-character-sanitization.js:152:3:152:99 | n.clone ... gi, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:152:41:152:41 | < | <script |

View File

@@ -144,4 +144,12 @@
content = content.replace(/<(script|iframe|video)[\s\S]*?<\/(script|iframe|video)>/g, '') // NOT OK
content = content.replace(/<(script|iframe|video)(.|\s)*?\/(script|iframe|video)>/g, '') // NOT OK
content = content.replace(/<[^<]*>/g, ""); // OK
n.cloneNode(false).outerHTML.replace(/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi, '').replace(/[\w:\-]+/gi, function(a) { // NOT OK
o.push({specified : 1, nodeName : a});
});
n.cloneNode(false).outerHTML.replace(/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi, '').replace(/[\w:\-]+/gi, function(a) { // NOT OK
o.push({specified : 1, nodeName : a});
});
});

View File

@@ -1,3 +1,3 @@
name: codeql/suite-helpers
version: 0.3.3
version: 0.3.4-dev
groups: shared

View File

@@ -1,5 +1,5 @@
name: codeql/python-all
version: 0.6.3
version: 0.6.4-dev
groups: python
dbscheme: semmlecode.python.dbscheme
extractor: python

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